[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H10FXRQPJ7M4BQ3ASGDCWS":3,"skill-same:01M6H10FXRQPJ7M4BQ3ASGDCWS":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":33,"linkOnly":34,"markdownContent":35,"markdownBody":36,"frontMatter":37,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":41,"repositoryHtmlUrl":42,"repositoryHomepageUrl":6,"ownerHtmlUrl":43,"ownerBlogUrl":44,"ownerDescription":45,"updatedAt":46,"install":47,"resources":60},"01M6H10FXRQPJ7M4BQ3ASGDCWS","watch-replication-lag-as-a-durability-gap",null,"Use when reads or failover depend on a replica. Measures replication lag continuously and treats it as the real RPO, alerting before a failover loses acknowledged data.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32],"watch","as","gap","replication","watch replication lag as a durability gap","alerting","data","rpo","use","it","failover","replica","when","2026-11-10 10:12:30",false,"---\nname: watch-replication-lag-as-a-durability-gap\ndescription: Use when reads or failover depend on a replica. Measures replication lag continuously and treats it as the real RPO, alerting before a failover loses acknowledged data.\n---\n\n# Watch Replication Lag as a Durability Gap\n\nThe promise \"we have a replica\" means nothing until you know the lag. Lag in seconds is the data a failover can lose; unmonitored lag turns a failover into silent data loss. Track it as a first-class durability metric.\n\n## Procedure\n\n1. Measure lag from the replica's perspective, not the primary's — the primary often cannot see a replica that stopped applying.\n2. Postgres: `SELECT now() - pg_last_xact_replay_timestamp() AS lag;` on the standby; use `pg_last_wal_receive_lsn()` vs `replay_lsn` for byte lag.\n3. MySQL: `SHOW REPLICA STATUS\\G` → `Seconds_Behind_Source` (and check `Replica_IO_Running`\u002F`SQL_Running` are both `Yes`).\n4. Redis\u002FKafka: consumer-group lag `kafka-consumer-groups.sh --describe --group x` or `redis-cli info replication` `master_link_down_since_seconds`.\n5. Export lag as a metric and alert on both bounds: warn at 5s, page at 60s, and page immediately on `null` lag (the standby lost connection).\n6. Alert when lag is trending up over an hour even if the instant value is low — a slow replica catches up only after the write burst ends.\n7. Tie the alert to the failover runbook: if lag exceeds the RPO window at failover time, the runbook must say to check before promoting.\n8. Test the metric by pausing replication (`SELECT pg_wal_replay_pause();`) and confirming the alert fires within the expected delay.\n\n## Pitfalls\n\n- Measuring lag on the primary, which reports 0 when the replica has silently stopped — the classic blind spot.\n- Alerting on `Seconds_Behind_Source` only; it can read 0 while the replica is stuck on a conflicting transaction and not applying.\n- Ignoring byte lag: a standby replaying a steady state can show 0 seconds yet be gigabytes behind after a bulk load.\n- A single async replica as the only copy, then promoting it during a primary outage and losing the un-replicated tail.\n- Cascading lag: a replica-of-a-replica inherits the parent's lag and hides it from the primary's monitoring.\n- Not accounting for lag during failover time itself; promotion freezes writes and widening the loss window further.\n- Muting the lag alert during a known batch job and forgetting to unmute, so the next real stall goes unnoticed.\n\n## Verification\n\n    psql -h standby -c \"SELECT now() - pg_last_xact_replay_timestamp() AS lag;\"\n    # alert test\n    psql -h primary -c \"SELECT pg_wal_replay_pause();\"  # on standby; lag should climb and page\n\nLag is exported, an induced stall raises the alert within the configured delay, and the failover runbook checks lag against the RPO before promoting.\n\nReport: \"Replication lag metric on \u003CN> replicas (warn 5s\u002Fpage 60s); induced stall alerted in \u003Cx>s; current max lag \u003Cy>s vs RPO \u003Cz>s.\"\n","# Watch Replication Lag as a Durability Gap\n\nThe promise \"we have a replica\" means nothing until you know the lag. Lag in seconds is the data a failover can lose; unmonitored lag turns a failover into silent data loss. Track it as a first-class durability metric.\n\n## Procedure\n\n1. Measure lag from the replica's perspective, not the primary's — the primary often cannot see a replica that stopped applying.\n2. Postgres: `SELECT now() - pg_last_xact_replay_timestamp() AS lag;` on the standby; use `pg_last_wal_receive_lsn()` vs `replay_lsn` for byte lag.\n3. MySQL: `SHOW REPLICA STATUS\\G` → `Seconds_Behind_Source` (and check `Replica_IO_Running`\u002F`SQL_Running` are both `Yes`).\n4. Redis\u002FKafka: consumer-group lag `kafka-consumer-groups.sh --describe --group x` or `redis-cli info replication` `master_link_down_since_seconds`.\n5. Export lag as a metric and alert on both bounds: warn at 5s, page at 60s, and page immediately on `null` lag (the standby lost connection).\n6. Alert when lag is trending up over an hour even if the instant value is low — a slow replica catches up only after the write burst ends.\n7. Tie the alert to the failover runbook: if lag exceeds the RPO window at failover time, the runbook must say to check before promoting.\n8. Test the metric by pausing replication (`SELECT pg_wal_replay_pause();`) and confirming the alert fires within the expected delay.\n\n## Pitfalls\n\n- Measuring lag on the primary, which reports 0 when the replica has silently stopped — the classic blind spot.\n- Alerting on `Seconds_Behind_Source` only; it can read 0 while the replica is stuck on a conflicting transaction and not applying.\n- Ignoring byte lag: a standby replaying a steady state can show 0 seconds yet be gigabytes behind after a bulk load.\n- A single async replica as the only copy, then promoting it during a primary outage and losing the un-replicated tail.\n- Cascading lag: a replica-of-a-replica inherits the parent's lag and hides it from the primary's monitoring.\n- Not accounting for lag during failover time itself; promotion freezes writes and widening the loss window further.\n- Muting the lag alert during a known batch job and forgetting to unmute, so the next real stall goes unnoticed.\n\n## Verification\n\n    psql -h standby -c \"SELECT now() - pg_last_xact_replay_timestamp() AS lag;\"\n    # alert test\n    psql -h primary -c \"SELECT pg_wal_replay_pause();\"  # on standby; lag should climb and page\n\nLag is exported, an induced stall raises the alert within the configured delay, and the failover runbook checks lag against the RPO before promoting.\n\nReport: \"Replication lag metric on \u003CN> replicas (warn 5s\u002Fpage 60s); induced stall alerted in \u003Cx>s; current max lag \u003Cy>s vs RPO \u003Cz>s.\"\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-12 02:28:42",{"source":8,"skillName":5,"commands":48,"prompt":58,"zipAvailable":59},[49,52,55],{"tool":50,"command":51},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill watch-replication-lag-as-a-durability-gap",{"tool":53,"command":54},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill watch-replication-lag-as-a-durability-gap",{"tool":56,"command":57},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill watch-replication-lag-as-a-durability-gap","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap\u002FSKILL.md",true,[61,65,71],{"path":62,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"SOURCE.md","REFERENCE","参考文档",367,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap\u002FSOURCE.md",{"path":72,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":73,"sourceHtmlUrl":74},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-watch-replication-lag-as-a-durability-gap\u002FTRUST.auto.yaml",[76,104,127,144,157,167],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":80,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":33},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":109,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":33},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[113,114,115,116,117,118,119,120,121,122,123,124,125,126],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":131,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":33},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[135,114,136,137,138,139,140,124,123,122,141,142,26,118,143,117,116],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","orders",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":108,"licenseFileUrl":148,"sourceHtmlUrl":149,"categories":150,"keywords":151,"publishedAt":33},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[152,153,115,154,155,125,123,156,121,120,118,117],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":158,"name":159,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":160,"sourceHtmlUrl":161,"categories":162,"keywords":163,"publishedAt":33},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[164,165,166],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":171,"sourceHtmlUrl":172,"categories":173,"keywords":174,"publishedAt":33},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[175,176,177,178,179,180,181,28,182,183,184],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]