[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"post-upcoming-monitor-assertions-and-incident":3,"related-upcoming-monitor-assertions-and-incident":33},{"id":4,"slug":5,"title":6,"excerpt":7,"content":8,"status":9,"tags":10,"coverMedia":15,"author":18,"createdAt":25,"updatedAt":26,"category":27},"c8ee5668-9bb7-4358-afe3-b16491d9f642","upcoming-monitor-assertions-and-incident","Upcoming: Monitor assertions and Incident","Our next revamp to monitor and incident feature","\u003Cp>When we built Crystade's active monitoring engine, we aimed for maximum evaluation depth. By pairing synthetic multi-protocol probes with custom Rice DSL check scripts, developers could inspect response payloads, parse headers, and evaluate latency thresholds right after a check log was generated.\u003C\u002Fp>\u003Cp>However, flexibility brought complexity. Writing imperative code to mix evaluation logic with action execution proved to be an operational drag for teams. Today, we are sunsetting imperative check scripts and rolling out \u003Cstrong>Declarative Assertions with Automated Incident Management\u003C\u002Fstrong>.\u003C\u002Fp>\u003Ch2>The Flaws of Imperative Check Scripts\u003C\u002Fh2>\u003Cp>Under the original system, a check script handled both evaluation logic and notification dispatching in a single script block:\u003C\u002Fp>\u003Cpre>\u003Ccode>if context.error == null &amp;&amp; context.metadata.rttMs &gt; 60 {\n    alerting.send({\n        header: \"Monitor [%s] notices high RTT from %s\"\n            .format(context.monitor.name, context.location),\n        message: \"Measured a RTT of %.2fms\\nCheck ID: %s\"\n            .format(context.metadata.rttMs, context.check.id),\n        footer: \"%s • Monitored by Crystade\"\n            .format(context.team.name),\n        deduplication: {\n            key: context.monitor.id + \":simple-uptime-check\",\n            ttl: \"1h\"\n        }\n    });\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>While powerful, this approach introduced severe friction:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>High Cognitive Overhead:\u003C\u002Fstrong> Developers had to learn platform-specific SDK functions like \u003Ccode>alerting.send(...)\u003C\u002Fcode> just to notify their team of a slow endpoint.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Zombie Incidents:\u003C\u002Fstrong> Incidents were reported when check scripts threw uncaught errors, but they lacked automatic state tracking to resolve those incidents once the service recovered.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Alert Fatigue &amp; Formatting Fragmentation:\u003C\u002Fstrong> Inlining messages inside scripts made internationalization (i18n), consistent formatting, and centralized deduplication nearly impossible.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Per-Monitor Silos:\u003C\u002Fstrong> Custom scripts were bound directly to individual monitors rather than shared across team workspaces.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Ch2>The Solution: Declarative Assertions &amp; State-Driven Incidents\u003C\u002Fh2>\u003Cp>We are decoupling \u003Cstrong>data collection\u003C\u002Fstrong> from \u003Cstrong>evaluation and lifecycle tracking\u003C\u002Fstrong>.\u003C\u002Fp>\u003Cp>Monitors focus entirely on making network requests. The outcome of a check is now evaluated against one or more \u003Cstrong>Assertions\u003C\u002Fstrong>—pure boolean conditions (\u003Ccode>true\u003C\u002Fcode> or \u003Ccode>false\u003C\u002Fcode>).\u003C\u002Fp>\u003Cpre>\u003Ccode>                    ┌─────────────────────────┐\n                    │    Monitor Execution    │\n                    └────────────┬────────────┘\n                                 │\n                         Generates Check Log\n                                 │\n                                 ▼\n                     ┌───────────────────────┐\n                     │ Evaluates Assertions  │\n                     └───────┬───────┬───────┘\n                             │       │\n             Assertion A =   │       │   Assertion B =\n                 FALSE       │       │       TRUE\n                             ▼       ▼\n                    ┌─────────┐     ┌─────────┐\n                    │  OPEN   │     │  CLOSE  │\n                    │ Incident│     │ Incident│\n                    └─────────┘     └─────────┘\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Ch3>1. Automated Incident Lifecycles\u003C\u002Fh3>\u003Cp>Each assertion on a monitor independently manages a single incident lifecycle:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>State Becomes \u003C\u002Fstrong>\u003Ccode>FALSE\u003C\u002Fcode>\u003Cstrong>:\u003C\u002Fstrong> If an assertion evaluates to \u003Ccode>false\u003C\u002Fcode> for longer than its designated tolerance window and no active incident exists for that assertion, an incident is automatically reported.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>State Becomes \u003C\u002Fstrong>\u003Ccode>TRUE\u003C\u002Fcode>\u003Cstrong>:\u003C\u002Fstrong> As soon as the target service recovers and the assertion evaluates back to \u003Ccode>true\u003C\u002Fcode> past the tolerance window, the associated incident automatically progresses to \u003Ccode>resolved\u003C\u002Fcode>.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cp>No manual intervention required, and no persistent zombie incidents.\u003C\u002Fp>\u003Ch3>2. Targeted Multi-Layer Monitoring\u003C\u002Fh3>\u003Cp>Because a single monitor can run multiple assertions, you no longer need separate monitors to test distinct layers of service health. A single HTTP execution can power two separate incidents:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Assertion 1 (Uptime):\u003C\u002Fstrong> \u003Ccode>context.error == null &amp;&amp; context.response.statusCode == 200\u003C\u002Fcode> ➡️ Triggers a \u003Ccode>critical\u003C\u002Fcode> incident if unreachable.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Assertion 2 (Performance):\u003C\u002Fstrong> \u003Ccode>context.metadata.rttMs &lt;= 100\u003C\u002Fcode> ➡️Triggers a \u003Ccode>minor\u003C\u002Fcode> incident if response latency degrades.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Reusable Templates and Shared Team Assertions\u003C\u002Fh2>\u003Cp>Custom assertion logic is no longer restricted to high-tier plans or trapped inside single monitors.\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Official &amp; Community Templates:\u003C\u002Fstrong> Select from pre-built assertions (e.g., HTTP status code validation, JSON body verification, TLS certificate validity) without writing code.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Team-Scoped Custom Assertions:\u003C\u002Fstrong> All plans—including Free—can now author custom assertions. Custom assertions become reusable team assets that can be attached to any monitor across your workspace.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Tier-Based Assertion Limits:\u003C\u002Fstrong> To balance infrastructure workload while keeping features accessible, plan limits govern how many assertions can run simultaneously on a single monitor:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Free:\u003C\u002Fstrong> Up to \u003Cstrong>1 assertion\u003C\u002Fstrong> per monitor.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Starter:\u003C\u002Fstrong> Up to \u003Cstrong>3 assertions\u003C\u002Fstrong> per monitor.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Standard:\u003C\u002Fstrong> Up to \u003Cstrong>5 assertions\u003C\u002Fstrong> per monitor.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Fine-Grained Link Configuration\u003C\u002Fh2>\u003Cp>When attaching an assertion to a monitor, you can customize how failure states present themselves to your engineering team and public status pages:\u003C\u002Fp>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Dynamic Message Templates:\u003C\u002Fstrong> Define clear alert context using dynamic variables:\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Cpre>\u003Ccode>\"{{assertionName}} failed on monitor {{monitorName}} (Location: {{location}})\"\u003C\u002Fcode>\u003C\u002Fpre>\u003Cul>\u003Cli>\u003Cp>\u003Cstrong>Incident Severity Override:\u003C\u002Fstrong> Explicitly map assertion failures to \u003Ccode>minor\u003C\u002Fcode>, \u003Ccode>major\u003C\u002Fcode>, or \u003Ccode>critical\u003C\u002Fcode> severities.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Assertion-Specific Tolerance Windows:\u003C\u002Fstrong> Override the monitor’s default tolerance window with granular thresholds per assertion (e.g., tolerate high latency for 5 minutes, but trigger an uptime failure after 1 minute).\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>7-Day Migration Strategy\u003C\u002Fh2>\u003Cp>To ensure zero disruption to your active monitoring setup:\u003C\u002Fp>\u003Col>\u003Cli>\u003Cp>\u003Cstrong>Dual Execution (Days 1–7):\u003C\u002Fstrong> We will soon rolling out the feature, both legacy check scripts and new assertions will run in parallel.\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>\u003Cstrong>Final Sunset:\u003C\u002Fstrong> On \u003Cstrong>August 15, 2026\u003C\u002Fstrong>, legacy Rice check scripts will be formally disabled.\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>Explore the official assertion templates in your Crystade workspace dashboard or create your first team assertion today.\u003C\u002Fp>","published",[11,12,13,14],"monitor","assertion","checkscript","incident",{"id":16,"url":17},"77987a12-88e7-4be5-b8a4-48228a354d45","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F08\u002Fe653f85a-1dd8-461c-8d17-92a821d1a307-Radar_pipeline_illustration_202608052109.jpeg",{"id":19,"name":20,"bio":21,"avatar":22},"a9be23b5-5867-4dd9-a173-2c11307c4ded","Anh Huynh","Building stuffs",{"id":23,"url":24},"64bab758-67e7-4a67-9636-bf1318378571","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F08\u002F3241ce71-aaa9-42a4-ac8d-552f8a465b6d-749022732_18368643070237484_2800348978445528529_n.jpg","2026-08-05T13:27:06.951Z","2026-08-07T07:44:01.680Z",{"id":28,"name":29,"slug":30,"description":31,"sortOrder":32},"ba8d305a-5b1b-4c2c-bb4a-63b5078030c1","Release Radar","release-radar","Product announcements, changelogs, new features, and version breakdowns.",0,{"data":34,"meta":113},[35,54,77,99],{"id":36,"slug":37,"title":38,"excerpt":39,"status":9,"tags":40,"createdAt":44,"coverMedia":45,"author":48,"category":53},"ec8539c3-9d70-447f-85c4-fa33905e15c9","crystade-expands-global-monitoring-with-8-new-locations","Crystade Expands Global Monitoring with 8 New Locations","We’ve added eight new monitoring locations across the globe, powered by Google Cloud Platform. Discover how broader coverage gives you deeper visibility into regional outages and latency.",[41,42,43],"location","monitoring","coverage","2026-09-08T01:44:44.205Z",{"id":46,"url":47},"3d567a26-571a-4a33-a630-aac803a729e4","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F09\u002F205284db-8b6b-4ff5-857b-4a38d1cf2235-Screenshot_2026-09-08_081218.png",{"id":49,"name":50,"bio":51,"avatar":52},"667a6b3d-5bfa-4550-bc3b-9888abff818b","Miles Carter","Dreaming in algorithms, debugging in reality. I believe every great product starts with curiosity and care.",null,{"id":28,"name":29,"slug":30,"description":31,"sortOrder":32},{"id":55,"slug":56,"title":57,"excerpt":58,"status":9,"tags":59,"createdAt":65,"coverMedia":66,"author":69,"category":76},"5345e691-1235-4216-9196-0dc196f9ba56","crystade-now-supports-telegram-zalo-alerts","Crystade Now Supports Telegram & Zalo Alerts","Get instant monitoring and incident notifications directly in Telegram and Zalo. Crystade now offers webhook delivery to these popular chat platforms, alongside Discord and Slack.",[60,61,62,63,64],"alerting","zalo","slack","discord","telegram","2026-09-06T09:31:47.092Z",{"id":67,"url":68},"cd6f1d94-c3ff-493b-87e9-f9362e50481f","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F09\u002Ff1b8c67a-374e-439a-a2b6-660b3cce10c8-4156e500-afec-44f4-81e8-aa83fe601139.png",{"id":70,"name":71,"bio":72,"avatar":73},"83c59046-756d-4aee-b49b-84a2cbd2491b","민준","Building pixels, logic, and a little happiness. Every line of code is another step toward something meaningful.",{"id":74,"url":75},"6bf343af-c883-4da7-a162-131f1e829094","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F08\u002F5a23300b-ff16-4e43-9c10-fd82a8b3c2f5-Boy_avatar_different_angle_202608041410.jpeg",{"id":28,"name":29,"slug":30,"description":31,"sortOrder":32},{"id":78,"slug":79,"title":80,"excerpt":81,"status":9,"tags":82,"createdAt":87,"coverMedia":88,"author":91,"category":98},"b1f30ded-83cf-47ad-8e8b-575a137a198e","3-new-developer-tools-from-crystade-cron-sla-and-curl","3 New Developer Tools from Crystade: Cron, SLA, and Curl","Crystade launches three free utilities: a cron expression builder, an SLA downtime calculator, and a curl command generator. Simplify scheduling, understand uptime targets, and test APIs faster.",[83,84,85,86,42],"cron","sla","downtime","curl","2026-09-05T10:43:25.825Z",{"id":89,"url":90},"ecd19c52-bd59-48a8-9fdc-abf8d73db8c0","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F09\u002F4cc9232e-8bd8-47f6-ace6-70f6112d833a-Men_and_robot_doing_mechanics_202609051743.jpeg",{"id":92,"name":93,"bio":94,"avatar":95},"189956e6-3c2c-4d0b-86a2-4243ca15fe7b","Mộng Hạ","Software engineer • Summer lover • Ocean soul ☁️🌊",{"id":96,"url":97},"90e26b21-25f7-4c69-9f26-aaca10372a9d","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F08\u002Fbbb5b302-03d3-42b0-8cf4-d0104055ddc3-Change_frame_angle_capture_neck_202608041402.jpeg",{"id":28,"name":29,"slug":30,"description":31,"sortOrder":32},{"id":100,"slug":101,"title":102,"excerpt":103,"status":9,"tags":104,"createdAt":107,"coverMedia":108,"author":111,"category":112},"85144cd1-d2a2-438f-92bc-e3f3658beab7","crystades-new-onboarding-flow","Crystade’s New Onboarding Flow","Crystade now asks a few simple questions after registration and automatically sets up your first monitor or cron job. No more blank dashboards—start getting value immediately.",[105,42,106],"onboarding","cronjob","2026-09-04T12:53:43.866Z",{"id":109,"url":110},"b60538a4-ca5c-48ef-a2c0-99353fd31fd0","https:\u002F\u002Fcdn.crystade.com\u002Fgrowth-media\u002F2026\u002F09\u002Fc0c2e413-f13c-4362-8b3d-a47ea3bfa981-Create_product_onboarding_illust__202609042013.jpeg",{"id":49,"name":50,"bio":51,"avatar":52},{"id":28,"name":29,"slug":30,"description":31,"sortOrder":32},{"total":114,"page":115,"pageSize":116},10,1,4]