All Experiments
╔══════════════════════════════════════════════════════════════╗
║  EXPERIMENT: Bidirectional Notion Sync                       ║
║  KEY METRIC: 5-second sync, 0 conflicts                      ║
║  workway.co                                                  ║
╚══════════════════════════════════════════════════════════════╝
ValidatedJanuary 21, 2026

Bidirectional Notion Sync

Two Notion workspaces. One shared database. Changes in seconds. Last edit wins.

What We Learned

Notion timestamps lie

We assumed last_edited_time meant the page was edited. It doesn't. Notion updates that timestamp when you view a page.

The fix: stop asking "when was this edited?" Start asking "are the values different?" Compare content. Not metadata.

Two-way sync needs a tiebreaker

Both databases have different values. Who wins? Without a rule, you get infinite loops. Base overwrites mirror. Mirror overwrites base. Repeat forever.

The fix: last-write-wins. Compare edit times on both pages. The more recent edit is the source of truth.

Cron has a one-minute floor

We wanted five-second sync. Cron can't do that. Cloudflare's minimum is one minute.

The fix: Durable Objects with alarms. Schedule the next run yourself. As fast as you want.

What Didn't Work

Time-based detectionNotion timestamps lie
Database-level checksDoesn't reflect page changes
Independent two-way passesCauses ping-pong
Cron for fast intervalsPlatform limit

What Did Work

Content comparisonCompare values, not metadata
Last-write-winsSimple conflict resolution
Single pass with trackingNo sync loops
Durable Object alarmsSub-minute scheduling
Hypothesis Validated

Content-based comparison with last-write-wins conflict resolution enables reliable bidirectional sync. Five-second intervals are achievable with Durable Object alarms. Launching next week.