@createdAt
Automatically set a Date field to the current timestamp when a record is created.
Automatically sets a Date field to the current timestamp when a record is created. The value is stored in the database and does not change on subsequent updates.
Syntax
model Post {
id Record @id
title String
createdAt Date @createdAt
}Behavior
- Date fields only —
@createdAtcan only be applied to fields of typeDate. - Set on creation — Defaults to
time::now()when a record is created and the field is not provided. - Can be overridden — You can provide an explicit value when creating a record. If you supply a value, the database uses your value instead of the automatic timestamp.
- Not auto-updated — The value is set once at creation. Subsequent updates do not change it — there is no NONE injection for
@createdAtfields (unlike@updatedAt). - Optional in CreateInput — The generated
CreateInputtype makes this field optional since the database provides a default. - Present in WhereInput — You can filter by
@createdAtfields.
Usage
// createdAt is auto-set to the current time
const post = await client.db.Post.create({
data: { title: 'Hello World' },
});
console.log(post.createdAt); // Date — e.g., 2025-01-15T10:30:00.000Z
// Or provide an explicit value
const backdatedPost = await client.db.Post.create({
data: {
title: 'Old Post',
createdAt: new Date('2024-01-01'),
},
});
console.log(backdatedPost.createdAt); // 2024-01-01T00:00:00.000ZFilter by creation time:
const recentPosts = await client.db.Post.findMany({
where: { createdAt: { gte: new Date('2025-01-01') } },
});Object Fields
@createdAt can be applied to Date fields within object definitions:
object ContactInfo {
email Email
createdAt Date @createdAt
}
model User {
id Record @id
contact ContactInfo
}When an object has @createdAt fields, Cerial generates a ContactInfoCreateInput type where those fields are optional:
const user = await client.db.User.create({
data: {
contact: { email: 'alice@example.com' },
// createdAt will be set to the current time
},
});Tuple Elements
@createdAt can also be applied to Date-type tuple elements:
tuple AuditStamp {
createdAt Date @createdAt,
source String
}
model Event {
id Record @id
audit AuditStamp
}The createdAt element becomes optional in create input — the database fills it in when absent.
Allowed On
| Construct | Allowed |
|---|---|
| Model fields (Date) | ✅ |
| Object fields (Date) | ✅ |
| Tuple elements (Date) | ✅ |
| Enum values | ❌ |
| Literal fields | ❌ |
Mutual Exclusions
@createdAt cannot be combined with any of these decorators on the same field — each field gets one default/timestamp strategy:
@updatedAt,@now— other timestamp decorators@default,@defaultAlways— custom default strategies@uuid,@uuid4,@uuid7— UUID auto-generation decorators
Example: Timestamps Pattern
A common pattern is to pair @createdAt with @updatedAt for full timestamp tracking:
model Article {
id Record @id
title String
content String
createdAt Date @createdAt
updatedAt Date @updatedAt
}const article = await client.db.Article.create({
data: { title: 'My Article', content: 'Hello' },
});
console.log(article.createdAt); // creation time
console.log(article.updatedAt); // same as createdAt initially
// After an update, only updatedAt changes
const updated = await client.db.Article.updateUnique({
where: { id: article.id },
data: { content: 'Updated content' },
});
console.log(updated.createdAt); // unchanged — still creation time
console.log(updated.updatedAt); // new timestamp — update timeComparison
| Decorator | Stored | Set on create | Updated on write | Can override |
|---|---|---|---|---|
@createdAt | Yes | Yes | No | Yes |
@updatedAt | Yes | Yes | Yes | Yes |
@now | No | N/A (computed) | N/A (computed) | No |