Cool, sounds like a plan then? Thanks for answering all the questions,
Steven!

чт, 22 січ. 2026 р. о 18:29 Steven Wu <[email protected]> пише:

> For row timestamp inheritance to work, I would need to implement the
> plumbing. So I would imagine existing rows would have null values because
> the inheritance plumbing was not there yet. This would be consistent with
> upgrade behavior for the V3 row lineage:
> https://iceberg.apache.org/spec/#row-lineage-for-upgraded-tables.
>
> On Thu, Jan 22, 2026 at 4:09 PM Anton Okolnychyi <[email protected]>
> wrote:
>
>> Also, do we have a concrete plan for how to handle tables that would be
>> upgraded to V4? What timestamp will we assign to existing rows?
>>
>> On Wed, Jan 21, 2026 at 3:59 PM Anton Okolnychyi <[email protected]>
>> wrote:
>>
>>> If we ignore temporal queries that need strict snapshot boundaries and
>>> can't be solved completely using row timestamps in case of mutations, you
>>> mentioned other use cases when row timestamps may be helpful like TTL and
>>> auditing. We can debate whether using CURRENT_TIMESTAMP() is enough for
>>> them, but I don't really see a point given that we already have row lineage
>>> in V3 and the storage overhead for one more field isn't likely to be
>>> noticable. One of the problems with CURRENT_TIMESTAMP() is the required
>>> action by the user. Having a reliable row timestamp populated automatically
>>> is likely to be better, so +1.
>>>
>>> пт, 16 січ. 2026 р. о 14:30 Steven Wu <[email protected]> пише:
>>>
>>>> Joining with snapshot history also has significant complexity. It
>>>> requires retaining the entire snapshot history with probably trimmed
>>>> snapshot metadata. There are concerns on the size of the snapshot history
>>>> for tables with frequent commits (like streaming ingestion). Do we maintain
>>>> the unbounded trimmed snapshot history in the same table metadata, which
>>>> could affect table metadata.json size? or store it separately somewhere
>>>> (like in catalog), which would require the complexity of multi-entity
>>>> transaction in catalog?
>>>>
>>>>
>>>> On Fri, Jan 16, 2026 at 12:07 PM Russell Spitzer <
>>>> [email protected]> wrote:
>>>>
>>>>> I've gone back and forth on the inherited columns. I think the thing
>>>>> which keeps coming back to me is that I don't
>>>>> like that the only way to determine the timestamp associated with a
>>>>> row update/creation is to do a join back
>>>>> against table metadata. While that's doable, It feels user unfriendly.
>>>>>
>>>>>
>>>>>
>>>>> On Fri, Jan 16, 2026 at 11:54 AM Steven Wu <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Anton, you are right that the row-level deletes will be a problem for
>>>>>> some of the mentioned use cases (like incremental processing). I have
>>>>>> clarified the applicability of some use cases to "tables with inserts and
>>>>>> updates only".
>>>>>>
>>>>>> Right now, we are only tracking modification/commit time (not
>>>>>> insertion time) in case of updates.
>>>>>>
>>>>>> On Thu, Jan 15, 2026 at 6:33 PM Anton Okolnychyi <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> I think there is clear consensus that making snapshot timestamps
>>>>>>> strictly increasing is a positive thing. I am also +1.
>>>>>>>
>>>>>>> - How will row timestamps allow us to reliably implement incremental
>>>>>>> consumption independent of the snapshot retention given that rows can be
>>>>>>> added AND removed in a particular time frame? How can we capture all
>>>>>>> changes by just looking at the latest snapshot?
>>>>>>> - Some use cases in the doc need the insertion time and some need
>>>>>>> the last modification time. Do we plan to support both?
>>>>>>> - What do we expect the behavior to be in UPDATE and MERGE
>>>>>>> operations?
>>>>>>>
>>>>>>> To be clear: I am not opposed to this change, just want to make sure
>>>>>>> I understand all use cases that we aim to address and what would be
>>>>>>> required in engines.
>>>>>>>
>>>>>>> чт, 15 січ. 2026 р. о 17:01 Maninder Parmar <
>>>>>>> [email protected]> пише:
>>>>>>>
>>>>>>>> +1 for improving how the commit timestamps are
>>>>>>>> assigned monotonically since this requirement has emerged over multiple
>>>>>>>> discussions like notifications, multi-table transactions, time travel
>>>>>>>> accuracy and row timestamps. It would be good to have a single 
>>>>>>>> consistent
>>>>>>>> way to represent and assign timestamps that could be leveraged across
>>>>>>>> multiple features.
>>>>>>>>
>>>>>>>> On Thu, Jan 15, 2026 at 4:05 PM Ryan Blue <[email protected]> wrote:
>>>>>>>>
>>>>>>>>> Yeah, to add my perspective on that discussion, I think my primary
>>>>>>>>> concern is that people expect timestamps to be monotonic and if they 
>>>>>>>>> aren't
>>>>>>>>> then a `_last_update_timestamp` field just makes the problem worse. 
>>>>>>>>> But it
>>>>>>>>> is _nice_ to have row-level timestamps. So I would be okay if we 
>>>>>>>>> revisit
>>>>>>>>> how we assign commit timestamps and improve it so that you get 
>>>>>>>>> monotonic
>>>>>>>>> behavior.
>>>>>>>>>
>>>>>>>>> On Thu, Jan 15, 2026 at 2:23 PM Steven Wu <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> We had an offline discussion with Ryan. I revised the proposal as
>>>>>>>>>> follows.
>>>>>>>>>>
>>>>>>>>>> 1. V4 would require writers to generate *monotonic* snapshot
>>>>>>>>>> timestamps. The proposal doc has a section that describes a 
>>>>>>>>>> recommended
>>>>>>>>>> implementation using lamport timestamps.
>>>>>>>>>> 2. Expose *last_update_timestamp* metadata column that inherits
>>>>>>>>>> from snapshot timestamp
>>>>>>>>>>
>>>>>>>>>> This is a relatively low-friction change that can fix the time
>>>>>>>>>> travel problem and enable use cases like latency tracking, temporal 
>>>>>>>>>> query,
>>>>>>>>>> TTL, auditing.
>>>>>>>>>>
>>>>>>>>>> There is no accuracy requirement on the timestamp values. In
>>>>>>>>>> practice, modern servers with NTP have pretty reliable wall clocks. 
>>>>>>>>>> E.g.,
>>>>>>>>>> Java library implemented this validation
>>>>>>>>>> <https://github.com/apache/iceberg/blob/035e0fb39d2a949f6343552ade0a7d6c2967e0db/core/src/main/java/org/apache/iceberg/TableMetadata.java#L369-L377>
>>>>>>>>>>  that
>>>>>>>>>> protects against backward clock drift up to one minute for snapshot
>>>>>>>>>> timestamps. Don't think we have heard many complaints of commit 
>>>>>>>>>> failure due
>>>>>>>>>> to that clock drift validation.
>>>>>>>>>>
>>>>>>>>>> Would appreciate feedback on the revised proposal.
>>>>>>>>>>
>>>>>>>>>> https://docs.google.com/document/d/1cXr_RwEO6o66S8vR7k3NM8-bJ9tH2rkh4vSdMXNC8J8/edit?tab=t.0
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Steven
>>>>>>>>>>
>>>>>>>>>> On Tue, Jan 13, 2026 at 8:40 PM Anton Okolnychyi <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Steven, I was referring to the fact that CURRENT_TIMESTAMP() is
>>>>>>>>>>> usually evaluated quite early in engines so we could theoretically 
>>>>>>>>>>> have
>>>>>>>>>>> another expression closer to the commit time. You are right, 
>>>>>>>>>>> though, it
>>>>>>>>>>> won't be the actual commit time given that we have to write it into 
>>>>>>>>>>> the
>>>>>>>>>>> files. Also, I don't think generating a timestamp for a row as it 
>>>>>>>>>>> is being
>>>>>>>>>>> written is going to be beneficial. To sum up, expression-based 
>>>>>>>>>>> defaults
>>>>>>>>>>> would allow us to capture the time the transaction or write starts, 
>>>>>>>>>>> but not
>>>>>>>>>>> the actual commit time.
>>>>>>>>>>>
>>>>>>>>>>> Russell, if the goal is to know what happened to the table in a
>>>>>>>>>>> given time frame, isn't the changelog scan the way to go? It would 
>>>>>>>>>>> assign
>>>>>>>>>>> commit ordinals based on lineage and include row-level diffs. How 
>>>>>>>>>>> would you
>>>>>>>>>>> be able to determine changes with row timestamps by just looking at 
>>>>>>>>>>> the
>>>>>>>>>>> latest snapshot?
>>>>>>>>>>>
>>>>>>>>>>> It does seem promising to make snapshot timestamps strictly
>>>>>>>>>>> increasing to avoid ambiguity during time travel.
>>>>>>>>>>>
>>>>>>>>>>> вт, 13 січ. 2026 р. о 16:33 Ryan Blue <[email protected]> пише:
>>>>>>>>>>>
>>>>>>>>>>>> > Whether or not "t" is an atomic clock time is not as
>>>>>>>>>>>> important as the query between time bounds making sense.
>>>>>>>>>>>>
>>>>>>>>>>>> I'm not sure I get it then. If we want monotonically increasing
>>>>>>>>>>>> times, but they don't have to be real times then how do you know 
>>>>>>>>>>>> what
>>>>>>>>>>>> notion of "time" you care about for these filters? Or to put it 
>>>>>>>>>>>> another
>>>>>>>>>>>> way, how do you know that your "before" and "after" times are 
>>>>>>>>>>>> reasonable?
>>>>>>>>>>>> If the boundaries of these time queries can move around a bit, by 
>>>>>>>>>>>> how much?
>>>>>>>>>>>>
>>>>>>>>>>>> It seems to me that row IDs can play an important role here
>>>>>>>>>>>> because you have the order guarantee that we seem to want for this 
>>>>>>>>>>>> use
>>>>>>>>>>>> case: if snapshot A was committed before snapshot B, then the rows 
>>>>>>>>>>>> from A
>>>>>>>>>>>> have row IDs that are always less than the rows IDs of B. The 
>>>>>>>>>>>> problem is
>>>>>>>>>>>> that we don't know where those row IDs start and end once A and B 
>>>>>>>>>>>> are no
>>>>>>>>>>>> longer tracked. Using a "timestamp" seems to work, but I still 
>>>>>>>>>>>> worry that
>>>>>>>>>>>> without reliable timestamps that correspond with some guarantee to 
>>>>>>>>>>>> real
>>>>>>>>>>>> timestamps, we are creating a feature that seems reliable but 
>>>>>>>>>>>> isn't.
>>>>>>>>>>>>
>>>>>>>>>>>> I'm somewhat open to the idea of introducing a snapshot
>>>>>>>>>>>> timestamp that the catalog guarantees is monotonically increasing. 
>>>>>>>>>>>> But if
>>>>>>>>>>>> we did that, wouldn't we still need to know the association 
>>>>>>>>>>>> between these
>>>>>>>>>>>> timestamps and snapshots after the snapshot metadata expires? My 
>>>>>>>>>>>> mental
>>>>>>>>>>>> model is that this would be used to look for data that arrived, 
>>>>>>>>>>>> say, 3
>>>>>>>>>>>> weeks ago on Dec 24th. Since the snapshots metadata is no longer 
>>>>>>>>>>>> around we
>>>>>>>>>>>> could use the row timestamp to find those rows. But how do we know 
>>>>>>>>>>>> that the
>>>>>>>>>>>> snapshot timestamps correspond to the actual timestamp range of 
>>>>>>>>>>>> Dec 24th?
>>>>>>>>>>>> Is it just "close enough" as long as we don't have out of order 
>>>>>>>>>>>> timestamps?
>>>>>>>>>>>> This is what I mean by needing to keep track of the association 
>>>>>>>>>>>> between
>>>>>>>>>>>> timestamps and snapshots after the metadata expires. Seems like 
>>>>>>>>>>>> you either
>>>>>>>>>>>> need to keep track of what the catalog's clock was for events you 
>>>>>>>>>>>> care
>>>>>>>>>>>> about, or you don't really care about exact timestamps.
>>>>>>>>>>>>
>>>>>>>>>>>> On Tue, Jan 13, 2026 at 2:22 PM Russell Spitzer <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> The key goal here is the ability to answer the question "what
>>>>>>>>>>>>> happened to the table in some time window. (before < t < after)?"
>>>>>>>>>>>>> Whether or not "t" is an atomic clock time is not as important
>>>>>>>>>>>>> as the query between time bounds making sense.
>>>>>>>>>>>>> Downstream applications (from what I know) are mostly
>>>>>>>>>>>>> sensitive to getting discrete and well defined answers to
>>>>>>>>>>>>> this question like:
>>>>>>>>>>>>>
>>>>>>>>>>>>> 1 < t < 2 should be exclusive of
>>>>>>>>>>>>> 2 < t < 3 should be exclusive of
>>>>>>>>>>>>> 3 < t < 4
>>>>>>>>>>>>>
>>>>>>>>>>>>> And the union of these should be the same as the query asking
>>>>>>>>>>>>> for 1 < t < 4
>>>>>>>>>>>>>
>>>>>>>>>>>>> Currently this is not possible because we have no guarantee of
>>>>>>>>>>>>> ordering in our timestamps
>>>>>>>>>>>>>
>>>>>>>>>>>>> Snapshots
>>>>>>>>>>>>> A -> B -> C
>>>>>>>>>>>>> Sequence numbers
>>>>>>>>>>>>> 50 -> 51 ->  52
>>>>>>>>>>>>> Timestamp
>>>>>>>>>>>>> 3 -> 1 -> 2
>>>>>>>>>>>>>
>>>>>>>>>>>>> This makes time travel always a little wrong to start with.
>>>>>>>>>>>>>
>>>>>>>>>>>>> The Java implementation only allows one minute of negative
>>>>>>>>>>>>> time on commit so we actually kind of do have this as a
>>>>>>>>>>>>> "light monotonicity" requirement but as noted above there is
>>>>>>>>>>>>> no spec requirement for this.  While we do have sequence
>>>>>>>>>>>>> number and row id, we still don't have a stable way of
>>>>>>>>>>>>> associating these with a consistent time in an engine independent 
>>>>>>>>>>>>> way.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ideally we just want to have one consistent way of answering
>>>>>>>>>>>>> the question "what did the table look like at time t"
>>>>>>>>>>>>> which I think we get by adding in a new field that is a
>>>>>>>>>>>>> timestamp, set by the Catalog close to commit time,
>>>>>>>>>>>>> that always goes up.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I'm not sure we can really do this with an engine expression
>>>>>>>>>>>>> since they won't know when the data is actually committed
>>>>>>>>>>>>> when writing files?
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Tue, Jan 13, 2026 at 3:35 PM Anton Okolnychyi <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> This seems like a lot of new complexity in the format. I
>>>>>>>>>>>>>> would like us to explore whether we can build the considered use 
>>>>>>>>>>>>>> cases on
>>>>>>>>>>>>>> top of expression-based defaults instead.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> We already plan to support CURRENT_TIMESTAMP() and similar
>>>>>>>>>>>>>> functions that are part of the SQL standard definition for 
>>>>>>>>>>>>>> default values.
>>>>>>>>>>>>>> This would provide us a way to know the relative row order. 
>>>>>>>>>>>>>> True, this
>>>>>>>>>>>>>> usually will represent the start of the operation. We may define
>>>>>>>>>>>>>> COMMIT_TIMESTAMP() or a similar expression for the actual commit 
>>>>>>>>>>>>>> time, if
>>>>>>>>>>>>>> there are use cases that need that. Plus, we may explore an 
>>>>>>>>>>>>>> approach
>>>>>>>>>>>>>> similar to MySQL that allows users to reset the default value on 
>>>>>>>>>>>>>> update.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> - Anton
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> вт, 13 січ. 2026 р. о 11:04 Russell Spitzer <
>>>>>>>>>>>>>> [email protected]> пише:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I think this is the right step forward. Our current
>>>>>>>>>>>>>>> "timestamp" definition is too ambiguous to be useful so 
>>>>>>>>>>>>>>> establishing
>>>>>>>>>>>>>>> a well defined and monotonic timestamp could be really
>>>>>>>>>>>>>>> great. I also like the ability for row's to know this value 
>>>>>>>>>>>>>>> without
>>>>>>>>>>>>>>> having to rely on snapshot information which can be expired.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Mon, Jan 12, 2026 at 11:03 AM Steven Wu <
>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I have revised the row timestamp proposal with the
>>>>>>>>>>>>>>>> following changes.
>>>>>>>>>>>>>>>> * a new commit_timestamp field in snapshot metadata that
>>>>>>>>>>>>>>>> has nano-second precision.
>>>>>>>>>>>>>>>> * this optional field is only set by the REST catalog server
>>>>>>>>>>>>>>>> * it needs to be monotonic (e.g. implemented using Lamport
>>>>>>>>>>>>>>>> timestamp)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> https://docs.google.com/document/d/1cXr_RwEO6o66S8vR7k3NM8-bJ9tH2rkh4vSdMXNC8J8/edit?tab=t.0#heading=h.efdngoizchuh
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>> Steven
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Fri, Dec 12, 2025 at 2:36 PM Steven Wu <
>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks for the clarification, Ryan.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> For long-running streaming jobs that commit periodically,
>>>>>>>>>>>>>>>>> it is difficult to establish the constant value of 
>>>>>>>>>>>>>>>>> current_timestamp across
>>>>>>>>>>>>>>>>> all writer tasks for each commit cycle. I guess streaming 
>>>>>>>>>>>>>>>>> writers may just
>>>>>>>>>>>>>>>>> need to write the wall clock time when appending a row to a 
>>>>>>>>>>>>>>>>> data file for
>>>>>>>>>>>>>>>>> the default value of current_timestamp.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Fri, Dec 12, 2025 at 1:44 PM Ryan Blue <
>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I don't think that every row would have a different
>>>>>>>>>>>>>>>>>> value. That would be up to the engine, but I would expect 
>>>>>>>>>>>>>>>>>> engines to insert
>>>>>>>>>>>>>>>>>> `CURRENT_TIMESTAMP` into the plan and then replace it with a 
>>>>>>>>>>>>>>>>>> constant,
>>>>>>>>>>>>>>>>>> resulting in a consistent value for all rows.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> You're right that this would not necessarily be the
>>>>>>>>>>>>>>>>>> commit time. But neither is the commit timestamp from 
>>>>>>>>>>>>>>>>>> Iceberg's snapshot.
>>>>>>>>>>>>>>>>>> I'm not sure how we are going to define "good enough" for 
>>>>>>>>>>>>>>>>>> this purpose. I
>>>>>>>>>>>>>>>>>> think at least `CURRENT_TIMESTAMP` has reliable and known 
>>>>>>>>>>>>>>>>>> behavior when you
>>>>>>>>>>>>>>>>>> look at how it is handled in engines. And if you want the 
>>>>>>>>>>>>>>>>>> Iceberg
>>>>>>>>>>>>>>>>>> timestamp, then use a periodic query of the snapshot stable 
>>>>>>>>>>>>>>>>>> to keep track
>>>>>>>>>>>>>>>>>> of them in a table you can join to. I don't think this rises 
>>>>>>>>>>>>>>>>>> to the need
>>>>>>>>>>>>>>>>>> for a table feature unless we can guarantee that it is 
>>>>>>>>>>>>>>>>>> correct.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Fri, Dec 12, 2025 at 1:19 PM Steven Wu <
>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> > Postgres `current_timestamp` captures the
>>>>>>>>>>>>>>>>>>> transaction start time [1, 2]. Should we extend the same 
>>>>>>>>>>>>>>>>>>> semantic to
>>>>>>>>>>>>>>>>>>> Iceberg: all rows added in the same snapshot should have 
>>>>>>>>>>>>>>>>>>> the same timestamp
>>>>>>>>>>>>>>>>>>> value?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Let me clarify my last comment.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> created_at TIMESTAMP WITH TIME ZONE DEFAULT
>>>>>>>>>>>>>>>>>>> CURRENT_TIMESTAMP)
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Since Postgres current_timestamp captures the
>>>>>>>>>>>>>>>>>>> transaction start time, all rows added in the same insert 
>>>>>>>>>>>>>>>>>>> transaction would
>>>>>>>>>>>>>>>>>>> have the same value as the transaction timestamp with the 
>>>>>>>>>>>>>>>>>>> column
>>>>>>>>>>>>>>>>>>> definition above.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> If we extend a similar semantic to Iceberg, all rows
>>>>>>>>>>>>>>>>>>> added in the same Iceberg transaction/snapshot should have 
>>>>>>>>>>>>>>>>>>> the same
>>>>>>>>>>>>>>>>>>> timestamp?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Ryan, I understand your comment for using
>>>>>>>>>>>>>>>>>>> current_timestamp expression as column default value, you 
>>>>>>>>>>>>>>>>>>> were thinking
>>>>>>>>>>>>>>>>>>> that the engine would set the column value to the wall 
>>>>>>>>>>>>>>>>>>> clock time when
>>>>>>>>>>>>>>>>>>> appending a row to a data file, right? every row would 
>>>>>>>>>>>>>>>>>>> almost have a
>>>>>>>>>>>>>>>>>>> different timestamp value.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Fri, Dec 12, 2025 at 10:26 AM Steven Wu <
>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> `current_timestamp` expression may not always carry the
>>>>>>>>>>>>>>>>>>>> right semantic for the use cases. E.g., latency tracking 
>>>>>>>>>>>>>>>>>>>> is interested in
>>>>>>>>>>>>>>>>>>>> when records are added / committed to the table, not when 
>>>>>>>>>>>>>>>>>>>> the record was
>>>>>>>>>>>>>>>>>>>> appended to an uncommitted data file in the processing 
>>>>>>>>>>>>>>>>>>>> engine.
>>>>>>>>>>>>>>>>>>>> Record creation and Iceberg commit can be minutes or even 
>>>>>>>>>>>>>>>>>>>> hours apart.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Row timestamp inherited from snapshot timestamp has no
>>>>>>>>>>>>>>>>>>>> overhead with the initial commit and has very minimal 
>>>>>>>>>>>>>>>>>>>> storage overhead
>>>>>>>>>>>>>>>>>>>> during file rewrite. Per-row current_timestamp would have 
>>>>>>>>>>>>>>>>>>>> distinct values
>>>>>>>>>>>>>>>>>>>> for every row and has more storage overhead.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> OLTP databases deal with small row-level transactions.
>>>>>>>>>>>>>>>>>>>> Postgres `current_timestamp` captures the transaction 
>>>>>>>>>>>>>>>>>>>> start time [1, 2].
>>>>>>>>>>>>>>>>>>>> Should we extend the same semantic to Iceberg: all rows 
>>>>>>>>>>>>>>>>>>>> added in the same
>>>>>>>>>>>>>>>>>>>> snapshot should have the same timestamp value?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>> https://www.postgresql.org/docs/current/functions-datetime.html
>>>>>>>>>>>>>>>>>>>> [2]
>>>>>>>>>>>>>>>>>>>> https://neon.com/postgresql/postgresql-date-functions/postgresql-current_timestamp
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> On Thu, Dec 11, 2025 at 4:07 PM Micah Kornfield <
>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Micah, are 1 and 2 the same? 3 is covered by this
>>>>>>>>>>>>>>>>>>>>>> proposal.
>>>>>>>>>>>>>>>>>>>>>> To support the created_by timestamp, we would need to
>>>>>>>>>>>>>>>>>>>>>> implement the following row lineage behavior
>>>>>>>>>>>>>>>>>>>>>> * Initially, it inherits from the snapshot timestamp
>>>>>>>>>>>>>>>>>>>>>> * during rewrite (like compaction), it should be
>>>>>>>>>>>>>>>>>>>>>> persisted into data files.
>>>>>>>>>>>>>>>>>>>>>> * during update, it needs to be carried over from the
>>>>>>>>>>>>>>>>>>>>>> previous row. This is similar to the row_id carry over 
>>>>>>>>>>>>>>>>>>>>>> for row updates.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Sorry for the short hand.  These are not the same:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> 1.  Insertion time - time the row was inserted.
>>>>>>>>>>>>>>>>>>>>> 2.  Create by - The system that created the record.
>>>>>>>>>>>>>>>>>>>>> 3.  Updated by - The system that last updated the
>>>>>>>>>>>>>>>>>>>>> record.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Depending on the exact use-case these might or might
>>>>>>>>>>>>>>>>>>>>> not have utility.  I'm just wondering if there will be 
>>>>>>>>>>>>>>>>>>>>> more example like
>>>>>>>>>>>>>>>>>>>>> this in the future.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> created_by column would incur likely significantly
>>>>>>>>>>>>>>>>>>>>>> higher storage overhead compared to the updated_by 
>>>>>>>>>>>>>>>>>>>>>> column. As rows are
>>>>>>>>>>>>>>>>>>>>>> updated overtime, the cardinality for this column in 
>>>>>>>>>>>>>>>>>>>>>> data files can be
>>>>>>>>>>>>>>>>>>>>>> high. Hence, the created_by column may not compress 
>>>>>>>>>>>>>>>>>>>>>> well. This is a similar
>>>>>>>>>>>>>>>>>>>>>> problem for the row_id column. One side effect of 
>>>>>>>>>>>>>>>>>>>>>> enabling row lineage by
>>>>>>>>>>>>>>>>>>>>>> default for V3 tables is the storage overhead of row_id 
>>>>>>>>>>>>>>>>>>>>>> column after
>>>>>>>>>>>>>>>>>>>>>> compaction especially for narrow tables with few columns.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I agree.  I think this analysis also shows that some
>>>>>>>>>>>>>>>>>>>>> consumers of Iceberg might not necessarily want to have 
>>>>>>>>>>>>>>>>>>>>> all these columns,
>>>>>>>>>>>>>>>>>>>>> so we might want to make them configurable, rather than 
>>>>>>>>>>>>>>>>>>>>> mandating them for
>>>>>>>>>>>>>>>>>>>>> all tables. Ryan's thought on default values seems like 
>>>>>>>>>>>>>>>>>>>>> it would solve the
>>>>>>>>>>>>>>>>>>>>> issues I was raising.
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>> Micah
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Thu, Dec 11, 2025 at 3:47 PM Ryan Blue <
>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> > An explicit timestamp column adds more burden to
>>>>>>>>>>>>>>>>>>>>>> application developers. While some databases require an 
>>>>>>>>>>>>>>>>>>>>>> explicit column in
>>>>>>>>>>>>>>>>>>>>>> the schema, those databases provide triggers to auto set 
>>>>>>>>>>>>>>>>>>>>>> the column value.
>>>>>>>>>>>>>>>>>>>>>> For Iceberg, the snapshot timestamp is the closest to 
>>>>>>>>>>>>>>>>>>>>>> the trigger timestamp.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Since the use cases don't require an exact timestamp,
>>>>>>>>>>>>>>>>>>>>>> this seems like the best solution to get what people 
>>>>>>>>>>>>>>>>>>>>>> want (an insertion
>>>>>>>>>>>>>>>>>>>>>> timestamp) that has clear and well-defined behavior. 
>>>>>>>>>>>>>>>>>>>>>> Since
>>>>>>>>>>>>>>>>>>>>>> `current_timestamp` is defined by the SQL spec, it makes 
>>>>>>>>>>>>>>>>>>>>>> sense to me that
>>>>>>>>>>>>>>>>>>>>>> we could use it and have reasonable behavior.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> I've talked with Anton about this before and maybe
>>>>>>>>>>>>>>>>>>>>>> he'll jump in on this thread. I think that we may need 
>>>>>>>>>>>>>>>>>>>>>> to extend default
>>>>>>>>>>>>>>>>>>>>>> values to include default value expressions, like 
>>>>>>>>>>>>>>>>>>>>>> `current_timestamp` that
>>>>>>>>>>>>>>>>>>>>>> is allowed by the SQL spec. That would solve the problem 
>>>>>>>>>>>>>>>>>>>>>> as well as some
>>>>>>>>>>>>>>>>>>>>>> others (like `current_date` or `current_user`) and would 
>>>>>>>>>>>>>>>>>>>>>> not create a
>>>>>>>>>>>>>>>>>>>>>> potentially misleading (and heavyweight) timestamp 
>>>>>>>>>>>>>>>>>>>>>> feature in the format.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> > Also some environments may have stronger clock
>>>>>>>>>>>>>>>>>>>>>> service, like Spanner TrueTime service.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Even in cases like this, commit retries can reorder
>>>>>>>>>>>>>>>>>>>>>> commits and make timestamps out of order. I don't think 
>>>>>>>>>>>>>>>>>>>>>> that we should be
>>>>>>>>>>>>>>>>>>>>>> making guarantees or even exposing metadata that people 
>>>>>>>>>>>>>>>>>>>>>> might mistake as
>>>>>>>>>>>>>>>>>>>>>> having those guarantees.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> On Tue, Dec 9, 2025 at 2:22 PM Steven Wu <
>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Ryan, thanks a lot for the feedback!
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Regarding the concern for reliable timestamps, we
>>>>>>>>>>>>>>>>>>>>>>> are not proposing using timestamps for ordering. With 
>>>>>>>>>>>>>>>>>>>>>>> NTP in modern
>>>>>>>>>>>>>>>>>>>>>>> computers, they are generally reliable enough for the 
>>>>>>>>>>>>>>>>>>>>>>> intended use cases.
>>>>>>>>>>>>>>>>>>>>>>> Also some environments may have stronger clock service, 
>>>>>>>>>>>>>>>>>>>>>>> like Spanner
>>>>>>>>>>>>>>>>>>>>>>> TrueTime service
>>>>>>>>>>>>>>>>>>>>>>> <https://docs.cloud.google.com/spanner/docs/true-time-external-consistency>
>>>>>>>>>>>>>>>>>>>>>>> .
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> >  joining to timestamps from the snapshots metadata
>>>>>>>>>>>>>>>>>>>>>>> table.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> As you also mentioned, it depends on the snapshot
>>>>>>>>>>>>>>>>>>>>>>> history, which is often retained for a few days due to 
>>>>>>>>>>>>>>>>>>>>>>> performance reasons.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> > embedding a timestamp in DML (like
>>>>>>>>>>>>>>>>>>>>>>> `current_timestamp`) rather than relying on an implicit 
>>>>>>>>>>>>>>>>>>>>>>> one from table
>>>>>>>>>>>>>>>>>>>>>>> metadata.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> An explicit timestamp column adds more burden to
>>>>>>>>>>>>>>>>>>>>>>> application developers. While some databases require an 
>>>>>>>>>>>>>>>>>>>>>>> explicit column in
>>>>>>>>>>>>>>>>>>>>>>> the schema, those databases provide triggers to auto 
>>>>>>>>>>>>>>>>>>>>>>> set the column value.
>>>>>>>>>>>>>>>>>>>>>>> For Iceberg, the snapshot timestamp is the closest to 
>>>>>>>>>>>>>>>>>>>>>>> the trigger timestamp.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> Also, the timestamp set during computation (like
>>>>>>>>>>>>>>>>>>>>>>> streaming ingestion or relative long batch computation) 
>>>>>>>>>>>>>>>>>>>>>>> doesn't capture the
>>>>>>>>>>>>>>>>>>>>>>> time the rows/files are added to the Iceberg table in a 
>>>>>>>>>>>>>>>>>>>>>>> batch fashion.
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> > And for those use cases, you could also keep a
>>>>>>>>>>>>>>>>>>>>>>> longer history of snapshot timestamps, like storing a 
>>>>>>>>>>>>>>>>>>>>>>> catalog's event log
>>>>>>>>>>>>>>>>>>>>>>> for long-term access to timestamp info
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> this is not really consumable by joining the regular
>>>>>>>>>>>>>>>>>>>>>>> table query with catalog event log. I would also 
>>>>>>>>>>>>>>>>>>>>>>> imagine catalog event log
>>>>>>>>>>>>>>>>>>>>>>> is capped at shorter retention (maybe a few months) 
>>>>>>>>>>>>>>>>>>>>>>> compared to data
>>>>>>>>>>>>>>>>>>>>>>> retention (could be a few years).
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>> On Tue, Dec 9, 2025 at 1:32 PM Ryan Blue <
>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> I don't think it is a good idea to expose
>>>>>>>>>>>>>>>>>>>>>>>> timestamps at the row level. Timestamps in metadata 
>>>>>>>>>>>>>>>>>>>>>>>> that would be carried
>>>>>>>>>>>>>>>>>>>>>>>> down to the row level already confuse people that 
>>>>>>>>>>>>>>>>>>>>>>>> expect them to be useful
>>>>>>>>>>>>>>>>>>>>>>>> or reliable, rather than for debugging. I think 
>>>>>>>>>>>>>>>>>>>>>>>> extending this to the row
>>>>>>>>>>>>>>>>>>>>>>>> level would only make the problem worse.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> You can already get this information by projecting
>>>>>>>>>>>>>>>>>>>>>>>> the last updated sequence number, which is reliable, 
>>>>>>>>>>>>>>>>>>>>>>>> and joining to
>>>>>>>>>>>>>>>>>>>>>>>> timestamps from the snapshots metadata table. Of 
>>>>>>>>>>>>>>>>>>>>>>>> course, the drawback there
>>>>>>>>>>>>>>>>>>>>>>>> is losing the timestamp information when snapshots 
>>>>>>>>>>>>>>>>>>>>>>>> expire, but since it
>>>>>>>>>>>>>>>>>>>>>>>> isn't reliable anyway I'd be fine with that.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> Some of the use cases, like auditing and
>>>>>>>>>>>>>>>>>>>>>>>> compliance, are probably better served by embedding a 
>>>>>>>>>>>>>>>>>>>>>>>> timestamp in DML
>>>>>>>>>>>>>>>>>>>>>>>> (like `current_timestamp`) rather than relying on an 
>>>>>>>>>>>>>>>>>>>>>>>> implicit one from
>>>>>>>>>>>>>>>>>>>>>>>> table metadata. And for those use cases, you could 
>>>>>>>>>>>>>>>>>>>>>>>> also keep a longer
>>>>>>>>>>>>>>>>>>>>>>>> history of snapshot timestamps, like storing a 
>>>>>>>>>>>>>>>>>>>>>>>> catalog's event log for
>>>>>>>>>>>>>>>>>>>>>>>> long-term access to timestamp info. I think that would 
>>>>>>>>>>>>>>>>>>>>>>>> be better than
>>>>>>>>>>>>>>>>>>>>>>>> storing it at the row level.
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>> On Mon, Dec 8, 2025 at 3:46 PM Steven Wu <
>>>>>>>>>>>>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> For V4 spec, I have a small proposal [1] to expose
>>>>>>>>>>>>>>>>>>>>>>>>> the row timestamp concept that can help with many use 
>>>>>>>>>>>>>>>>>>>>>>>>> cases like temporal
>>>>>>>>>>>>>>>>>>>>>>>>> queries, latency tracking, TTL, auditing and 
>>>>>>>>>>>>>>>>>>>>>>>>> compliance.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> This *_last_updated_timestamp_ms * metadata
>>>>>>>>>>>>>>>>>>>>>>>>> column behaves very similarly to the
>>>>>>>>>>>>>>>>>>>>>>>>> *_last_updated_sequence_number* for row lineage.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>    - Initially, it inherits from the snapshot
>>>>>>>>>>>>>>>>>>>>>>>>>    timestamp.
>>>>>>>>>>>>>>>>>>>>>>>>>    - During rewrite (like compaction), its values
>>>>>>>>>>>>>>>>>>>>>>>>>    are persisted in the data files.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Would love to hear what you think.
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>>>>>>>>>>>>> Steven
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>>>>>>>>>>> https://docs.google.com/document/d/1cXr_RwEO6o66S8vR7k3NM8-bJ9tH2rkh4vSdMXNC8J8/edit?usp=sharing
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>>>>>

Reply via email to