Migrating from PlayFab to Crux: A 10-Step Checklist (2026)
Step-by-step 2026 migration checklist from Microsoft PlayFab to Crux - exporting player data, mapping APIs, handling cloud functions, billing transition, and zero-downtime cutover.
Microsoft PlayFab is a mature live-ops backend, but indie and mid-size studios increasingly hit the same set of friction points: confusing usage-based pricing that's hard to forecast, mandatory Azure account dependencies, an enormous API surface that punishes simple games, and rising concern about long-term Microsoft commitment to PlayFab as a standalone product (GameSparks was sunset in 2024). This guide walks through migrating a live game's backend from PlayFab to Crux with zero downtime.
Migration takes 1-3 weeks for a typical indie game, depending on how deep you've gone into PlayFab Cloud Script and Azure Functions. The data export itself is fast; rewriting integrations is the real work.
Before You Start: Is Crux the Right Replacement?
Crux replaces PlayFab cleanly if your game uses PlayFab primarily for: player auth, save sync (player-scoped JSON documents), leaderboards, friends, matchmaking, virtual currencies, inventory, and dedicated-server registry. Crux does not currently replace PlayFab if you depend heavily on Azure-specific features like Application Insights, Azure A/B testing, or PlayFab Multiplayer Servers (the orchestration layer - Supercraft hosting is the equivalent but you'd treat it as a separate product).
Read the PlayFab vs Crux comparison first if you're still in the decision phase.
If PlayFab's current Development Mode limit, Foundation Mode eligibility, or metered paid plans pushed you to migrate, that breakdown explains which path applies to your title.
Shortcut: the compatibility layer
The rewrite is usually not the backend, it is the call sites. crux-playfab-compat
keeps them: it accepts PlayFab's request shapes, returns PlayFab's
{ code, status, data } envelope, and supports both the callback and the
promise/Task style, so the diff is which client you construct.
npm install crux-playfab-compat
const PlayFabClientAPI = new PlayFabClientCompat(
CruxClient.forPlayer(baseUrl, projectId, environmentId, apiKey),
);
// unchanged from your PlayFab codebase
PlayFabClientAPI.GetUserData({ Keys: ["save"] }, (res, err) => { /* ... */ });
It ships for JavaScript/TypeScript, for Unity (C#) and for Godot (GDScript) - between
them, where most PlayFab titles actually live. The Unity and Godot versions come inside
those SDK packages; the JavaScript one is on npm. It covers what an ordinary title calls every session: the
Login* methods, GetUserData/UpdateUserData,
GetTitleData, GetLeaderboard,
GetLeaderboardAroundPlayer, UpdatePlayerStatistics,
GetUserInventory, AddUserVirtualCurrency,
SubtractUserVirtualCurrency and the friends calls.
Everything outside that set throws a named error rather than quietly doing nothing. That is deliberate: a stub that silently succeeds looks like it worked, and for a currency or receipt call, "looks like it worked" is somebody's money. Methods with no Crux equivalent - characters, receipt validation, shared groups, trading, segments, push, CDN content, Photon tokens - tell you what is missing and what to do instead.
Three behaviours differ on purpose, and the layer does not paper over them:
AddFriendreturnsCreated: false. PlayFab friends immediately; Crux sends a request the other player accepts. Reportingtruewould be a lie your UI would act on.- Leaderboard
Positionstays 0-based to match PlayFab, converted from Crux's 1-based ranks. GetUserData/UpdateUserDatashare one Crux document, so multi-key writes stay atomic. Updates merge,nulldeletes, and the read version is passed back for optimistic concurrency.
ExecuteCloudScript is not supported, and that is the one gap worth planning
around before you start - see the step below.
The 10-Step Checklist
Step 1: Audit your PlayFab usage
List every PlayFab API call your client and server code makes today. Group them by category: auth, player data, leaderboards, virtual currency, inventory, cloud script / Azure Functions, multiplayer matchmaking, analytics events. This list becomes your migration spec.
Pull a 30-day call-volume report from the PlayFab dashboard. Anything called <1% of total volume can usually be deferred or dropped during migration.
Step 2: Map PlayFab APIs to Crux equivalents
| PlayFab | Crux equivalent | Notes |
|---|---|---|
| LoginWithEmailAddress / LoginWithCustomID | POST /v1/auth/login (email + password) / POST /v1/auth/anonymous | Direct mapping. Crux also supports OAuth (Google, Apple, Steam). |
| UpdateUserData / GetUserData | Player JSON docs with patch semantics | Crux uses RFC 6902 JSON patch. Map PlayFab key/value pairs into a single document. |
| UpdatePlayerStatistics / GetLeaderboard | Leaderboards API | Direct mapping. Seasonal boards supported. |
| AddUserVirtualCurrency / SubtractUserVirtualCurrency | Currencies API with atomic transactions | Direct mapping; atomic semantics for multi-currency operations. |
| GrantItemToUser / GetUserInventory | Inventory API | Direct mapping. Stack-based and unique-item modes both supported. |
| PlayFab Cloud Script (JavaScript) / Azure Functions | Your own service, called by Crux webhooks | Crux does not execute your code, but it does call yours: subscribe to events and Crux POSTs a signed payload when they fire. If your CloudScript already runs on Azure Functions, keep it and change only what invokes it. Still the largest item in the migration. |
| Matchmaking API | Crux matchmaker | Map your queue config; rule-set semantics differ slightly. |
| GetTitleData (live config) | Live config bundles, environment-based | Crux ships environment-aware bundles; map your title-data keys to bundle versions. |
Step 3: Export your PlayFab player data
Use PlayFab's GetPlayerSegmentReport or the data export feature in the PlayFab dashboard to dump all player accounts, statistics, virtual currency, and inventory state. The export typically produces JSON or CSV chunks.
Critical: capture player IDs alongside the data. You'll need to map PlayFab IDs to Crux IDs in step 7.
Step 4: Set up your Crux project
Create a Crux project at crux.supercraft.host/pricing (start on free tier for migration testing). Configure your environments - typically dev, staging, prod. Generate API keys for each.
Step 5: Build the import script
Write a one-shot import script that iterates your PlayFab export and creates equivalent Crux entities:
- For each PlayFab player: create a Crux player with anonymous-promote auth, then merge in their email if present
- For each statistic: write to the matching Crux leaderboard
- For each virtual currency: write to the matching Crux currency
- For each inventory item: write to Crux inventory
- Write a mapping table:
playfab_id -> crux_id
Test on staging first. Run import in batches of 1,000 players to monitor for errors.
Step 6: Rehome your Cloud Script logic
This is the longest single step, and the one to be clear-eyed about: Crux does not execute your code. There is no Crux equivalent to drop CloudScript into. The logic moves to a service you run. For each function:
- Identify the trigger (player call, scheduled task, server-side validation)
- If it already runs on Azure Functions, keep it. Only the invocation path changes - your client calls your function directly instead of going through PlayFab
- If it is PlayFab-hosted JavaScript, it needs a home: your game server, an existing backend service, or a small function on any provider
- Have it talk to Crux with a server token. Anything that grants currency or validates a purchase must never be reachable with a client key
- Write tests; the production data is the only audit you'll get
Crux calls you back. Rehoming the logic does not mean losing the
trigger. Register an HTTPS endpoint against events like
achievement.unlocked or stat.updated, and Crux POSTs a
signed payload to your service when they happen - so "when they hit 100 kills, grant
the reward" still fires from the backend, it just runs in your process instead of
PlayFab's. Each delivery carries an HMAC-SHA256 signature and a timestamp inside the
signed material, so you can verify it came from us and that it is not a replay.
Step 7: Update your client SDK calls
Replace PlayFab SDK calls in your game client with Crux SDK calls. Wrap each in a feature flag so you can toggle between PlayFab and Crux during the cutover.
Use the playfab_id -> crux_id mapping from step 5 so existing players see their progression seamlessly after the switch.
Step 8: Stage a parallel-write period
For 1-2 weeks before cutover, run both backends in parallel. Every player action writes to both PlayFab (current source of truth) and Crux (shadow). This catches mapping bugs before they hit production.
Compare data integrity daily. If Crux diverges from PlayFab by more than 0.1%, fix the import script and re-run.
Step 9: Cutover
Pick a low-traffic window (usually a weekday off-hour for your game's primary audience). Flip the feature flag from PlayFab to Crux. Monitor for 4 hours minimum.
Keep PlayFab in read-only mode for 30 days as a rollback safety net. Most migrations don't need to roll back, but the 30-day buffer covers edge cases.
Step 10: Decommission PlayFab
After 30 days of stable Crux-only operation:
- Cancel your PlayFab subscription / Azure billing
- Delete API keys
- Archive the import scripts and mapping tables (don't delete - they're audit trail)
- Remove PlayFab SDKs from your client codebase in the next release
Common Pitfalls
- Cloud Script rewrites are 60% of the work, not 20%. Plan timeline accordingly.
- PlayFab "PlayerData" keys are flat; Crux documents are nested JSON. Decide on a schema before you import - fixing it after is painful.
- PlayFab analytics events do NOT migrate. If you depend on PlayFab's event tracking, plan a separate analytics solution (PostHog, Mixpanel, GameAnalytics). Crux does not ingest gameplay events.
- Don't skip the parallel-write period. Cutting over without it is the #1 source of post-migration data loss.
Cost Comparison After Migration
Indie studios moving from PlayFab to Crux typically see 30-60% cost reduction at the 1,000-10,000 MAU scale, primarily because Crux's flat tier pricing is predictable while PlayFab's usage-based bills scale unpredictably with API call volume.
| Scale | Typical PlayFab cost / mo | Crux cost / mo |
|---|---|---|
| 100 MAU | $0 (free tier) | Free |
| 1,000 MAU | $30-80 (highly variable) | Free |
| 10,000 MAU | $200-500 | Free |
| 50,000 MAU | $800-2,500 | $79 |
Bottom Line
Migrating from PlayFab to Crux is not a weekend project, but it's a tractable 1-3 week effort for most indie games. The biggest wins post-migration are predictable pricing, no Azure account dependency, simpler API surface, and the option to unify your backend with Supercraft dedicated-server hosting under one vendor. The biggest cost is rewriting Cloud Script logic - plan for it.
Ready to start? Sign up for the Crux free tier and start with the parallel-write period in a staging environment. The Crux documentation covers the SDK quickstart for Unity, Godot, Roblox, and JavaScript.