Time-to-Wallet: Key Metric
1) TTW definition and variants
Time-to-Wallet (TTW) - the time from the user's action to the actual availability of funds in the target wallet/account. For iGaming, we use two main types:- TTW₍deposit ₎: 'click "Pay" → money is available to play'.
- Includes UX/3DS, authorization with PSP/bank, confirmation and balance recording.
TTW₍payout ₎: 'Click "Withdraw" → money on an external wallet/bank'.
Includes risk/KYC/SoF checks, same-method/ND gates, corridor orchestration, confirmation at PSP/scheme and posting at bank/wallet.
2) Why TTW is a P&L metric
Conversion and AR: quick deposit ↑ probability of first bet/session.
Retention and trust: quick conclusions ↓ churn and support tickets.
Cost: instant-rails are often more expensive ⇒ you need a "speed ↔ price" balance.
Operational risk: TTW's long tails create clusters of incidents and chargeback.
3) TTW decomposition by stages
3. 1. Deposits
1. UI/Checkout (Render, Validation, 3DS)
2. PSP Auth (authorize)
3. Capture/Booking (confirmation, balance update)
4. Fallback/Retry (при soft-decline)
`TTW₍deposit₎ = t_UI + t_3DS + t_auth + t_capture + t_write_balance`
3. 2. Conclusions
1. Pre-checks (KYC/SoF, ND/same-method, RG/AML limits)
2. Risk decision (auto/manual)
3. Payout orchestration (corridor selection: SEPA Instant/PIX/Faster Payments/RTP/push-to-card/A2A/e-wallet)
4. PSP API (initiate → accepted)
5. Network/Banks (clearing/posting)
6. Reconcile & Notify
`TTW₍payout₎ = t_precheck + t_risk + t_initiation + t_network + t_posting + t_notify`
4) SLAs and target levels
Deposit p95: ≤ 10-20 sec (wallets/one-tap), ≤ 30-60 sec (cards with 3DS).
Output p95:- Instant rails (SEPA Instant/PIX/FPS/RTP, push-to-wallet/card): ≤ 15–30 мин.
- Standard A2A/SEPA Credit: T + 0/T + 1 banking (hours/day).
- International SWIFT: 1-3 banking days.
- p99 is important to keep in communication (ETA bands) to manage expectations.
5) Measurement: units, windows, sampling
Unit of measure: transaction (deposit/payout).
Aggregation: p50/p90/p95/p99, SLA-hit% (share in ETA), tails (tail> 2 × p95).
Slices: method/corridor/PSP/MID/GEO/BIN clusters/time of day/channel.
Exclude: canceled/duplicates (idempotency), manual pauses at the request of the player.
6) Data model (minimum)
sql payments. timeline (
tx_id PK, kind -- DEPOSIT PAYOUT,
user_id, method, corridor, provider, mid, iso2, currency, amount_minor BIGINT,
t_ui_start TIMESTAMP, t_3ds_start TIMESTAMP, t_3ds_end TIMESTAMP,
t_auth_req TIMESTAMP, t_auth_ok TIMESTAMP,
t_capture_ok TIMESTAMP, -- депозиты t_precheck_start TIMESTAMP, t_precheck_ok TIMESTAMP, -- выводы t_risk_start TIMESTAMP, t_risk_ok TIMESTAMP,
t_payout_initiated TIMESTAMP, t_network_posted TIMESTAMP,
t_wallet_available TIMESTAMP, -- final availability status TEXT, decline_code TEXT, meta JSONB
);
sla. catalog (
kind, method, corridor, geo, p95_target_seconds INT, p99_target_seconds INT, eta_text TEXT
);
7) SQL calculation templates
7. 1. TTW by deposit (total and by method)
sql
SELECT method,
PERCENTILE_CONT(0. 95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (t_wallet_available - t_ui_start))) AS p95_ttw_sec,
PERCENTILE_CONT(0. 99) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (t_wallet_available - t_ui_start))) AS p99_ttw_sec,
COUNT() AS attempts,
100. 0 AVG((EXTRACT(EPOCH FROM (t_wallet_available - t_ui_start)) <= s. p95_target_seconds)::int) AS sla_hit_p95_pct
FROM payments. timeline t
JOIN sla. catalog s ON s. kind='DEPOSIT' AND s. method=t. method
WHERE t. kind='DEPOSIT'
AND t. status='SUCCESS'
AND t. t_ui_start BETWEEN:from AND:to
GROUP BY 1;
7. 2. TTW by outputs (corridors)
sql
SELECT corridor,
PERCENTILE_CONT(0. 50) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (t_wallet_available - t_precheck_start))) AS p50_sec,
PERCENTILE_CONT(0. 95) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (t_wallet_available - t_precheck_start))) AS p95_sec,
PERCENTILE_CONT(0. 99) WITHIN GROUP (ORDER BY EXTRACT(EPOCH FROM (t_wallet_available - t_precheck_start))) AS p99_sec,
100. 0 AVG((EXTRACT(EPOCH FROM (t_wallet_available - t_precheck_start)) <= s. p95_target_seconds)::int) AS sla_hit_p95_pct,
COUNT() AS payouts
FROM payments. timeline t
JOIN sla. catalog s ON s. kind='PAYOUT' AND s. corridor=t. corridor
WHERE t. kind='PAYOUT' AND t. status='SUCCESS'
AND t. t_precheck_start BETWEEN:from AND:to
GROUP BY 1;
7. 3. Bottleneck decomposition (outputs)
sql
SELECT corridor,
AVG(EXTRACT(EPOCH FROM (t_precheck_ok - t_precheck_start))) AS precheck_sec,
AVG(EXTRACT(EPOCH FROM (t_risk_ok - t_risk_start))) AS risk_sec,
AVG(EXTRACT(EPOCH FROM (t_network_posted - t_payout_initiated))) AS network_sec,
AVG(EXTRACT(EPOCH FROM (t_wallet_available - t_network_posted))) AS posting_sec
FROM payments. timeline
WHERE kind='PAYOUT' AND status='SUCCESS'
AND t_precheck_start BETWEEN:from AND:to
GROUP BY 1
ORDER BY network_sec DESC;
7. 4. SLA bricks and long tails
sql
SELECT method, corridor,
COUNT() FILTER (WHERE EXTRACT(EPOCH FROM (t_wallet_available - COALESCE(t_ui_start, t_precheck_start))) > s. p95_target_seconds) AS breaches,
COUNT() AS total,
100. 0 COUNT() FILTER (WHERE EXTRACT(EPOCH FROM (t_wallet_available - COALESCE(t_ui_start, t_precheck_start))) > s. p95_target_seconds)
/ NULLIF(COUNT(),0) AS breach_pct
FROM payments. timeline t
JOIN sla. catalog s ON s. kind=t. kind AND COALESCE(s. method, t. method)=t. method AND COALESCE(s. corridor, t. corridor)=t. corridor
WHERE t. status='SUCCESS' AND (t. t_ui_start BETWEEN:from AND:to OR t. t_precheck_start BETWEEN:from AND:to)
GROUP BY 1,2
ORDER BY breach_pct DESC;
8) Dashboards and KPIs
TTW p50/p95/p99 by method/corridor/PSP/GEO/BIN cluster.
SLA-hit%, tail share (> 2 × p95), incidents (annotations).
Requested → Pre-check OK → Risk OK → Initiated → Posted → Available.
Correlations: TTW vs AR/deposit conversion, TTW vs support tickets/CSAT, TTW vs churn.
Cost: 'cost _ per _ payout' and 'take-rate' along the corridor vs TTW win.
9) Alerts
p95 breach: p95 TTW along the corridor/PSP> SLA X minutes.
Tail spike: share> 2 × p95 increased> Y% in Z hours.
Pre-check stall: t_precheck_start is, t_precheck_ok is not> 15 min (auto-escalation).
Risk backlog: t_risk_start is, t_risk_ok is not> threshold (manual queue).
Network/posting anomaly: a sharp increase in 'network _ sec' by GEO/bank.
Policy drift - events without required timestamps.
10) How to accelerate TTW (practices)
Deposits
One-tap wallets/Apple Pay/Google Pay, network tokens.
Frictionless 3DS by risk, embedding 3DS in modal.
PSP cascade on BIN/GEO/health, retray only on soft-decline.
Prefetch 3DS/ACS channels, aggressive timeouts on degradation.
Conclusions
Pre-KYC/pre-SoF for frequent players; pre-approval for ≤ threshold amounts.
Instance corridors: SEPA Instant/Faster Payments/RTP/PIX/push-to-card/wallet.
Cascade of corridors: instant → fast A2A → standard SEPA/SWIFT (with ETA).
Same-method & ND logic are automated, without manual checks.
Time windows: avoid cut-off and bank "narrow" hours.
Provider health-feed and auto-failover with 'network _ sec' growth.
Communications
ETA at the start + progress statuses ("Check," "Initiated," "Credited").
Proactive delay alerts> SLAs, honest reasons and expected time.
11) Economics and trade-offs
Instant costs more: compare uplift CSAT/churn/retention vs bps/fixed.
Tails are more expensive than p50: optimizations on p95 give a greater P&L effect.
Local differences: in some GEO, the "fast but expensive" channel pays off better.
12) Playbook incident
1. PSP/corridor specific p95 growth
Auto-reroute to the backup corridor, reducing the degraded limit.
Communication to players with updated ETA, ticket to the provider.
2. Risk backlog (manual checks)
Enable pre-approval for X ≤ amounts, redistribute queue, temporarily raise auto-pass thresholds.
3. Bank posting delays on GEO
Bypass with another correspondent bank/wallet, temporarily disable the "slow" corridor for new applications.
4. 3DS/ACS degradation (deposits)
Force frictionless/alternate DS where risk policy allows, or cascade to another PSP.
13) A/B tests around TTW
Instant vs Standard corridor on part of the traffic (guardrails: CBR bps, cost/payout, CSAT).
Pre-KYC copyright/flow, ETA wording, order of methods.
Metrics: TTW p95, SLA-hit%, tickets/1000 trx, AR/conversion, churn 7/30.
14) Best practices (short)
1. Measure by stages and keep timestamps in a single pattern.
2. Optimize p95/p99, not just the median.
3. Embed instant-rails where the economy converges.
4. Do pre-KYC/SoF/approval for repetitive scenarios.
5. Auto-cascade corridors and PSP, react to health.
6. Say honest ETA and statuses, notify delays.
7. Store SLAs in a catalog and check SLA-hit% for each slice.
8. Tie TTW to CSAT/tickets/churn in dashboards.
9. Post Incidents: Capture causes, change rules/threshold timers.
10. Version the event schema, validate the completeness of the timestamps.
15) Implementation checklist
- TTW definitions for deposits/withdrawals agreed with product/financials.
- Timestamps by stage in 'payments. timeline`; SLA directory.
- Dashboards p50/p95/p99, SLA-hit%, tails; p95/tails/backlogs alerts.
- PSP/corridor cascades, health-feed and auto-failover.
- Pre-KYC/SoF and pre-approval policies; ND/same-method automated.
- ETA communications and status tracker for the user.
- Speed ↔ price economic model along corridors.
- Incident playbooks and the post-mortem process.
- A/B tests of TTW improvements with guardrails.
- Regular audit of data completeness and correctness of calculations.
Summary
Time-to-Wallet is not just "output speed." It is an end-to-end metric of payment experience affecting conversion, retention and P & L. Measure TTW by stages, optimize p95/p99, connect instant-rails and cascades, remove friction through pre-KYC/approval and automate ND/same-method checks. Strong telemetry, honest ETAs and ready-made playbooks will make payments fast, predictable and economically viable.