tightrelay

Work offline. Sync later.

tightrelay is the sync service for native apps. Your app keeps its local database. tightrelay delivers the changes to every device and resolves conflicts on the server.

  • macOS
  • iOS
  • Windows
  • Android

One document, three devices

Take Windows offline and edit there, then edit on the Mac and reconnect Windows. The later change wins, everywhere.

api.tightrelay.comserver_seq 1

    What tightrelay handles for you

    The service has no app-specific tables. It stores JSON documents, versions them and distributes changes. Your app’s schema is configuration, not server code.

    A glass device with a broken connection; pending changes wait as golden dots.

    Offline first

    The app writes to its own database, whether SwiftData, SQLite or Room. The SDK tracks every change and syncs as soon as the network is back.

    A glass security chip with a key symbol.

    Devices instead of passwords

    The key lives in the Secure Enclave, TPM or Android Keystore. New devices find their account via iCloud Keychain or Block Store; others pair by QR.

    Several glass spheres linked by threads of light to one shared disc.

    Shared data

    Shared spaces for teams or businesses, with invites by QR code and roles to manage, edit or read.

    The server settles conflicts

    Every change carries a hybrid logical clock timestamp. Per document, the later change wins, and every device ends up in the same state.

    Subscriptions from the App Store and Google Play

    If you want, tightrelay only syncs with an active subscription. The server verifies purchases, renewals, expiry and refunds itself. When a subscription lapses, sync pauses and the data stays.

    Schemas without a deploy

    You manage collections and JSON Schemas in the console. Every new version is checked, and only changes that don’t break older app versions pass. Unknown fields are preserved.

    One SDK per platform

    Swift, C# and Kotlin, with no third-party dependencies. All three run the same test vectors and behave the same.

    • Your database stays. You write a small adapter around one transaction, and the SDK does the rest.
    • Push, pull, retry with backoff and device clock skew are built in.
    • You decide when to sync: at launch, shortly after changes, in the background.
    let client = TightRelayClient(
        configuration: .init(baseURL: api, appId: "stundennachweis",
                             clientSchema: 1, deviceName: "Mac"),
        store: MySwiftDataStore(),
        identities: KeychainIdentityStore(appId: "stundennachweis"),
        recovery: ICloudKeychainRecoveryStore(appId: "stundennachweis"))
    
    try await client.create(collection: "clients", data: ["name": "Miller Ltd"])
    try await client.update(id, set: ["archived": true])  // merge
    try await client.delete(id)                           // tombstone
    let report = try await client.sync()                  // push, then pull

    How a sync works

    Each round is a push and a pull over HTTPS. Every request is signed with the device key.

    1. Change locally

      The app saves as usual. The SDK stamps the change with the device clock and queues it for upload.

    2. Upload

      The server validates the schema, compares timestamps and only accepts newer data. If the change is older, the device gets the current version back.

    3. Number

      Every accepted change gets the next number in its space, without gaps, even with concurrent uploads.

    4. Download

      The device fetches everything after its last number, page by page, one transaction each. If the connection drops, nothing is lost.

    What tightrelay deliberately leaves out

    A small scope keeps the service easy to understand and predictable. If your app needs one of these, tightrelay isn’t the right fit today.

    No real-time pushDevices sync after changes, at launch and every few minutes. Too slow for chat, plenty for work data.

    No field-level mergingWhen two devices change the same document, the later change wins as a whole.

    No filesPhotos and PDFs don’t belong in the sync. A document is at most 64 KB.

    No web clientBuilt for native apps with their own database, not for browsers.

    In production: Stundennachweis

    The time tracker for freelancers syncs clients, projects and entries through tightrelay. A running timer shows up on the other devices right away.

    Start a timer on two devices at once and a rule on the server stops the older one. Rules like this run in the same transaction as the upload.

    Mac and iPhoneSwiftUI, SwiftData, Secure Enclave
    WindowsWinUI 3, SQLite, TPM
    AndroidJetpack Compose, Room, Keystore
    ServerRust, PostgreSQL 16, Hetzner

    Your app, in sync on every device

    Sign up in the console. Once your account is approved, create your app, define its collections and add the SDK.