your push.
your stack.
Clone the repo. Create a D1, a KV, two queues, a Durable Object. Drop your APNs and FCM credentials in. Two wrangler deploys and you have a push notification service that nobody else can see, throttle, or take down. AGPL-3.0 means you can fork it and keep it forever.
# clone + install
git clone https://github.com/akshitkrnagpal/edgepush.git
cd edgepush && pnpm install
# create cloudflare resources
cd apps/api
pnpm wrangler d1 create edgepush
pnpm wrangler kv namespace create edgepush-cache
pnpm wrangler queues create edgepush-dispatch
pnpm wrangler queues create edgepush-dispatch-dlq
pnpm wrangler queues create edgepush-webhook
pnpm wrangler queues create edgepush-webhook-dlq
# paste IDs into wrangler.jsonc, then:
pnpm wrangler secret put ENCRYPTION_KEY
pnpm wrangler secret put BETTER_AUTH_SECRET
pnpm wrangler secret put GITHUB_CLIENT_ID
pnpm wrangler secret put GITHUB_CLIENT_SECRET
# migrate + deploy api
pnpm db:migrate:remote
pnpm deploy
# deploy dashboard
cd ../web && pnpm deploy
# done. send your first push:
edgepush send <token> --title "from my own infra"HOSTED_MODE=false
A single env var that disables every hosted-tier behavior: no plan limits, no quota counter, no Stripe webhook, no retention purge, no operator digest emails. Self-host is a strict superset, not a stripped-down build.
your secret key
ENCRYPTION_KEY is a 32-byte secret you generate with openssl, store in wrangler secrets, and never share. Every APNs .p8 and FCM service account JSON is AES-GCM encrypted under that key before it touches D1.
your D1, your audit log
Every send, every receipt, every credential change writes to your own D1. Operator scripts (replay-dlq, inspect-app) ship in the repo so you can run incident response from your terminal.
active credential probes
The same hourly cron that runs on the hosted tier: probes every stored APNs and FCM credential against Apple and Google, marks them ● ok / ● broken / ● topic mismatch, emails you (if RESEND_API_KEY is set) when something breaks.
real workers infra
D1 + KV + Queues with DLQ + Durable Objects. No external dependencies. No nodejs containers. Cold start is sub-50ms because there is no cold start, it's all native Worker primitives.
MIT sdk + cli
The server is AGPL but @edgepush/sdk and @edgepush/cli are MIT. You can embed the SDK in a closed-source backend or mobile app without copyleft obligations.
agpl-3.0. Semver from v1.0 onward.
Typed client. Works in any fetch-capable runtime.
login, send, receipt. Bundles the SDK inline.
edgepush has no built-in update notifier. Watch the GitHub repo for releases or subscribe to the changelog feed if you want to know when there's something new to pull. Self-host upgrades are a `git pull` + `pnpm install` + `pnpm db:migrate:remote` + pnpm deploy. Additive migrations (new tables, new columns) are safe to apply before deploying; breaking migrations need the deprecate-then-drop pattern.
? What does AGPL-3.0 mean for me?
If you run edgepush as an internal service inside your company, AGPL is invisible, you don't have to do anything. AGPL only matters if you operate a hosted edgepush AS A SERVICE for third parties (like edgepush.dev does). In that case the AGPL requires you to publish any modifications you make to the server code. SDK + CLI are MIT, so they're unaffected.
? Will my self-hosted instance get updates automatically?
No, by design. Self-host means you're in charge. You git pull when you want to upgrade. The hosted tier on edgepush.dev moves at its own pace; your fork moves at yours. The CHANGELOG and the GitHub releases page are how you find out what's new.
? Is the self-hosted version a different product than the hosted one?
Same code. The only difference is HOSTED_MODE, false (self-host default) skips the billing and retention paths. Every other feature, including credential probes, dead-letter queue, dashboard, audit log, webhooks, is on by default.
? What does it cost to run on Cloudflare?
For most teams, $0. Workers paid plan is $5/mo and unlocks the cron triggers + larger queue burst limits, but you can run on the free tier for trials. D1 + KV + Queues are all in-tier on free or paid. The biggest cost variable is Workers requests above 100K/day, which kicks in at $0.30 per million.
? Can I migrate between self-host and the hosted tier?
One direction is easy, the other is manual. Self-host → hosted: sign up at edgepush.dev, re-upload credentials, switch your server's API URL. Hosted → self-host: follow the SELFHOST.md guide and re-upload credentials. There's no automated migration tool because both sides are storing native APNs and FCM tokens, your token list is portable by design.
? What if I need help?
Open a GitHub issue. The hosted tier customers get priority email support; self-hosters get the same code, same docs, same SELFHOST.md guide, but support is community-driven through issues.
Run edgepush on your infrastructure.
SELFHOST.md walks the full path: prerequisites, resource creation, secrets, migrations, first sign-in, smoke test, troubleshooting. About 20 minutes if you've used Cloudflare Workers before.