Release highlights: 1.16
Smarter timestamp handling
This release brings a major cleanup and unification of how dlt handles timestamps and timezones. Both tz-aware and naive timestamps are now processed consistently across normalizers and destinations. dlt now also preserves the exact timestamp type when using incremental cursors, preventing subtle mismatches during reloads.
It also fixes several tricky edge cases — such as nanosecond precision in MSSQL — and ensures that all time types behave as documented (always naive, in UTC). Destinations now explicitly declare which timestamp formats they support, so dlt adjusts automatically.
Example:
@dlt.resource(
name='my_table',
columns={
"my_column": {
"data_type": "timestamp",
"timezone": True}}
)
def my_resource():
...
# Output:
# naive timestamp → UTC tz-aware
# "2024-05-01 12:00:00" → "2024-05-01 12:00:00+00:00"
# tz-aware timestamp with timezone=False → UTC converted, then naive
# "2024-05-01 12:00:00+02:00" → "2024-05-01 10:00:00"
The result: predictable, precise timestamp behavior across all sources, transformations, and destinations.
dlt Education now in docs
Our free education courses are now part of the official documentation and can be launched directly in Google Colab. Try them here.

Visualization updates
-
New beta dashboard
The Streamlit app is now replaced by the dlt Dashboard. Run
dlt dashboardto explore your pipelines with an improved interface and real-time insights. Learn more here.
-
Export schema graphs with
dlt.Schema.to_dot()
Shout-out to new contributors
Big thanks to our newest contributors:
Full release notes