feat: start time travel at inbound request entry via x-td-root-timestamp header#62
Closed
feat: start time travel at inbound request entry via x-td-root-timestamp header#62
Conversation
sohil-kshirsagar
approved these changes
Feb 5, 2026
sohankshirsagar
approved these changes
Feb 5, 2026
Contributor
Author
|
Not needed anymore since we use root span timestamp for |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Enable deterministic time travel at the very start of an inbound replay request by reading a new
x-td-root-timestampHTTP header sent by the CLI. This fixes replay deviations caused by time-sensitive code executing before the first outbound span is matched - most notablydjango-cachalot, which incorporatestimezone.now()into Redis cache keys.Previously, time travel was only activated per-outbound-span (when a mock was matched). This meant any time-dependent logic that ran before the first outbound call (e.g., cache key generation, session expiry checks) would use wall-clock time instead of the recorded time, causing cache key mismatches and divergent code paths during replay.
Changes
drift/instrumentation/django/middleware.py: ReadHTTP_X_TD_ROOT_TIMESTAMPfrom Django'sMETAheaders and callstart_time_travel()immediately in_handle_replay_request, before any downstream middleware or view code runs.drift/instrumentation/wsgi/handler.py: Readx-td-root-timestampfrom WSGI environ headers and callstart_time_travel()at the start of_handle_replay_request.drift/instrumentation/fastapi/instrumentation.py: Readx-td-root-timestampfrom ASGI headers and callstart_time_travel()at the start of_handle_replay_request.Design notes
HTTP_X_TD_ROOT_TIMESTAMPformat, so the Django middleware reads fromhttp_x_td_root_timestampin the lowercased headers dict, while WSGI/FastAPI use the standardx-td-root-timestamp.x-td-root-timestampheader to replay requests.