{"id":24642413,"url":"https://github.com/notrab/turso-cdn","last_synced_at":"2025-05-12T17:28:42.184Z","repository":{"id":273710354,"uuid":"920573136","full_name":"notrab/turso-cdn","owner":"notrab","description":"Create your own edge replicas and self host a multi-region write-through cache proxy for serverless SQLite with Turso.","archived":false,"fork":false,"pushed_at":"2025-01-23T09:01:46.000Z","size":21,"stargazers_count":18,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-07T23:08:30.670Z","etag":null,"topics":["libsql","proxy","replication","serverless","sqlite","turso"],"latest_commit_sha":null,"homepage":"https://turso.tech","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/notrab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-22T11:50:18.000Z","updated_at":"2025-04-23T19:56:44.000Z","dependencies_parsed_at":"2025-01-27T22:31:10.269Z","dependency_job_id":null,"html_url":"https://github.com/notrab/turso-cdn","commit_stats":null,"previous_names":["notrab/libsql-proxy","notrab/turso-cdn"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrab%2Fturso-cdn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrab%2Fturso-cdn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrab%2Fturso-cdn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notrab%2Fturso-cdn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/notrab","download_url":"https://codeload.github.com/notrab/turso-cdn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253786755,"owners_count":21964219,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["libsql","proxy","replication","serverless","sqlite","turso"],"created_at":"2025-01-25T13:11:35.479Z","updated_at":"2025-05-12T17:28:42.128Z","avatar_url":"https://github.com/notrab.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Turso CDN\n\nThis guide will help you self host a multi-region write-through cache proxy for serverless SQLite with [Turso](https://turso.tech).\n\nTurso CDN provides similar guarantees to Turso's (deprecated) Edge Replicas.\n\n## How It Works\n\n1. **Regional Routing**: Fly.io automatically routes requests to the nearest proxy instance using anycast IPs.\n2. **Local Replicas**: Each region maintains a local SQLite file that syncs with the primary database.\n3. **Sync Interval**: The local replicas sync every 60 seconds (configurable) with the primary database.\n\n```plaintext\nClient (Asia)     Client (US)    Client (EU)\n     |               |              |\n     v               v              v\n[Fly Anycast IP - Global Load Balancing]\n     |               |              |\n     v               v              v\n[sin proxy]     [bos proxy]    [lhr proxy]     # Each has local SQLite replica\n     |               |              |\n     \\               |              /\n      \\              |             /\n       \\             |            /\n        \\            v           /\n         `----\u003e [Turso/LibSQL] \u003c´          # Primary database\n                Sync every 60s\n```\n\n## Prerequisites\n\n- Fly.io account and [`flyctl`](https://fly.io/docs/flyctl/install/) installed\n- [Turso](https://turso.tech) cloud account and database created\n\n## Quickstart\n\n1. Clone the repository\n\n```bash\ngit clone https://github.com/notrab/turso-cdn\ncd turso-cdn\n```\n\n2. Create a Fly app:\n\n```bash\nfly launch\n```\n\nWhen prompted:\n\n- Choose a unique app name\n- Select \"No\" for Postgres/Redis\n- Select \"No\" for immediate deployment\n\n3. Create volumes in your desired regions:\n\n```bash\nfly volumes create libsql_data --size 10 --region lhr\nfly volumes create libsql_data --size 10 --region sin\nfly volumes create libsql_data --size 10 --region bos\n```\n\n4. Set your Turso database credentials:\n\n```bash\nfly secrets set TURSO_DATABASE_URL=libsql://your-database.turso.io\nfly secrets set TURSO_AUTH_TOKEN=your-auth-token\nfly secrets set PROXY_AUTH_TOKEN=a-random-string\n\n# Optional: Set the sync interval (default is 60 seconds)\n# fly secrets set TURSO_SYNC_INTERVAL=30\n```\n\n5. Deploy to multiple regions:\n\n```bash\nfly deploy\nfly scale count 3 --region lhr,sin,bos\n```\n\n6. Check that each region is running:\n\n```bash\nfly status\n```\n\n## Using the CDN\n\nUpdate your client applications to use the proxy:\n\n\u003e [!NOTE]\n\u003e Make sure to use `https://` for the proxy URL and not `libsql://`.\n\n\u003e [!NOTE]\n\u003e The `authToken` here is the `PROXY_AUTH_TOKEN` you set in the Fly secrets, this is created by you and not Turso.\n\n```ts\nimport { createClient } from \"@libsql/client/web\";\n\nconst client = createClient({\n  url: \"https://your-cdn.fly.dev\",\n  authToken: process.env.PROXY_AUTH_TOKEN,\n});\n\n// The client will automatically connect to the nearest region\nconst result = await client.execute(\"SELECT 1\");\n```\n\n### Adding Edge Replicas\n\nTo expand to new regions:\n\n1. Create a volume in the new region:\n\n```bash\nfly volumes create libsql_data --size 10 --region new-region\n```\n\n2. Scale the application:\n\n```bash\nfly scale count 4 --region lhr,sin,bos,new-region\n```\n\n### Removing Edge Replicas\n\n1. Scale down the regions:\n\n```bash\n# Scale down to just one instance in the primary region\nfly scale count 1\n\n# Or keep multiple regions but reduce count\nfly scale count 1 --region lhr,sin\n\n# Remove a specific region entirely while keeping others\nfly scale count 0 --region sin\n```\n\n2. Remove the volumes not longer used:\n\n```bash\n# List volumes first to see what exists\nfly volumes list\n\n# Remove volume in a specific region\nfly volumes destroy libsql_data --region sin\n```\n\n## Monitoring, Troubleshooting and Configuration\n\nSOme of the commands and steps below help you customise the proxy to your individual needs.\n\n### Check Replica Status\n\nView the logs from a specific region:\n\n```bash\nfly logs --region sin\n```\n\n### Verify Local Database\n\nSSH into an instance to check the local database:\n\n```bash\nfly ssh console\nls -l /app/data/local.db\n```\n\n### Performance Testing\n\nTest latency from different regions by passing the `fly-prefer-region` header:\n\n```bash\ncurl -s -X POST https://your-cdn.fly.dev/v2/pipeline \\\n  -w \"\\nTotal time: %{time_total}s\\n\" \\\n  -H \"fly-prefer-region: sin\" \\\n  -H \"Authorization: Bearer your-proxy-auth-secret\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"requests\":[{\"type\":\"execute\",\"stmt\":{\"sql\":\"SELECT 1\",\"want_rows\":true}},{\"type\":\"close\"}]}'\n```\n\n### Custom Sync Interval\n\nYou can change the sync interval by setting the `TURSO_SYNC_INTERVAL` secret:\n\n```bash\nfly secrets set TURSO_SYNC_INTERVAL=30 # 30 seconds\n```\n\nIf not set, the value defaults to `60` seconds.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotrab%2Fturso-cdn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotrab%2Fturso-cdn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotrab%2Fturso-cdn/lists"}