🔗 screenshotrun.com — Screenshot API for developers
🔗 snapshotarchive.com — Website monitoring & archiving
🔗 watchcron.com — Cron job monitoring
Building in public. PHP, Laravel, APIs.
Unpopular opinion: if your cron job doesn't have external monitoring, it doesn't exist. Cron fails silently. No crash report. No alert. Just... nothing happens. Your cleanup script stopped 2 weeks ago? You'll find out when the disk fills up. One heartbeat ping at the end of the script. That's …
Unpopular opinion: if your cron job doesn't have external monitoring, it doesn't exist. Cron fails silently. No crash report. No alert. Just... nothing happens. Your cleanup script stopped 2 weeks ago? You'll find out when the disk fills up. One heartbeat ping at the end of the script. That's …
PSA: if you're using Puppeteer for screenshots and getting blank images on SPAs, don't just bump the timeout. Set waitUntil to 'networkidle0' AND add a waitForSelector for your main content element. The page "loads" way before the content actually renders. Saved me a ton of debugging on a Reac…
PSA: if you're using Puppeteer for screenshots and getting blank images on SPAs, don't just bump the timeout. Set waitUntil to 'networkidle0' AND add a waitForSelector for your main content element. The page "loads" way before the content actually renders. Saved me a ton of debugging on a Reac…
Hot take: most teams don't know their site has visual regressions until a user screenshots it and posts it in Slack. Your CI pipeline catches broken tests. Nothing catches a design drift that happened over six months. That's a monitoring gap.
Hot take: most teams don't know their site has visual regressions until a user screenshots it and posts it in Slack. Your CI pipeline catches broken tests. Nothing catches a design drift that happened over six months. That's a monitoring gap.
Tracked a client's pricing page daily for 3 months. They changed prices 11 times — and reverted 4 of those changes within 48 hours. Without visual snapshots you'd never know the reverts happened. Server logs just show "page updated." The actual price that was displayed? Gone unless you capture…
Tracked a client's pricing page daily for 3 months. They changed prices 11 times — and reverted 4 of those changes within 48 hours. Without visual snapshots you'd never know the reverts happened. Server logs just show "page updated." The actual price that was displayed? Gone unless you capture…
TIL that crontab silently drops jobs if the previous run hasn't finished yet. Not overlapping — just gone. Spent 20 minutes wondering why a report only generated once instead of hourly. The script took 70 minutes to complete. cron just skipped every other invocation. flock is your friend here.
TIL that crontab silently drops jobs if the previous run hasn't finished yet. Not overlapping — just gone. Spent 20 minutes wondering why a report only generated once instead of hourly. The script took 70 minutes to complete. cron just skipped every other invocation. flock is your friend here.
Ran a backup job for 6 months before realizing it wrote to /tmp which got cleared every reboot. The backups were there... until they weren't. Now I verify every scheduled task actually produces output where it should. Lesson tax: 3 months of missing snapsho…
Ran a backup job for 6 months before realizing it wrote to /tmp which got cleared every reboot. The backups were there... until they weren't. Now I verify every scheduled task actually produces output where it should. Lesson tax: 3 months of missing snapsho…
Learned this the hard way: networkidle0 in Puppeteer does NOT mean the page finished rendering. It means no network requests fired for 500ms. React apps that fetch data on mount? The idle fires after the JS bundle loads but before the API response comes back. Screenshot = blank component with …
Learned this the hard way: networkidle0 in Puppeteer does NOT mean the page finished rendering. It means no network requests fired for 500ms. React apps that fetch data on mount? The idle fires after the JS bundle loads but before the API response comes back. Screenshot = blank component with …
Found out our competitor changed their pricing page layout three weeks ago. Didn't notice because we only check manually "when we remember to." Automated screenshots would've caught it day one. Adding that to the monitoring list this week.
Found out our competitor changed their pricing page layout three weeks ago. Didn't notice because we only check manually "when we remember to." Automated screenshots would've caught it day one. Adding that to the monitoring list this week.
Spent an hour debugging why screenshots came out blank. Turns out the page had a prefers-color-scheme media query and headless Chrome defaults to light mode — but the app's "light mode" was white text on white background because someone shipped a broken theme toggle.…
Spent an hour debugging why screenshots came out blank. Turns out the page had a prefers-color-scheme media query and headless Chrome defaults to light mode — but the app's "light mode" was white text on white background because someone shipped a broken theme toggle.…
Honest question for anyone running scheduled tasks in production: how do you know they actually ran? Not "the cron daemon is running" — how do you verify the actual script executed and produced the expected output?
Honest question for anyone running scheduled tasks in production: how do you know they actually ran? Not "the cron daemon is running" — how do you verify the actual script executed and produced the expected output?
Unpopular opinion: if your monitoring only checks HTTP 200, you don't have monitoring. You have a false sense of security. A page can return 200 and show a blank white screen. A 200 with a stack trace in the body. A 200 serving yesterday's cached data. Check the content, not just the status co…
Unpopular opinion: if your monitoring only checks HTTP 200, you don't have monitoring. You have a false sense of security. A page can return 200 and show a blank white screen. A 200 with a stack trace in the body. A 200 serving yesterday's cached data. Check the content, not just the status co…
TIL that Chrome DevTools Protocol has a Page.captureScreenshot that accepts a "clip" parameter — you can screenshot just a specific DOM region without capturing the full page and cropping after. Saves a ton of memory on long pages.
TIL that Chrome DevTools Protocol has a Page.captureScreenshot that accepts a "clip" parameter — you can screenshot just a specific DOM region without capturing the full page and cropping after. Saves a ton of memory on long pages.
Headless Chrome eats about 300MB per tab. Spin up five parallel screenshot jobs and you are at 1.5GB before your app even starts. Learned this the hard way when our worker kept getting OOM-killed and nobody could figure out why. The fix wasn't more RAM — it was a job queue with concurrency lim…
Headless Chrome eats about 300MB per tab. Spin up five parallel screenshot jobs and you are at 1.5GB before your app even starts. Learned this the hard way when our worker kept getting OOM-killed and nobody could figure out why. The fix wasn't more RAM — it was a job queue with concurrency lim…
A client asked why their homepage looked different than last week. Nobody had pushed any code. Turns out a third-party widget updated itself and broke the layout. Without before/after screenshots, we would've spent hours guessing what changed.
A client asked why their homepage looked different than last week. Nobody had pushed any code. Turns out a third-party widget updated itself and broke the layout. Without before/after screenshots, we would've spent hours guessing what changed.
Screenshot tip: if your captures look like the mobile version of a site, check your viewport width. Most responsive breakpoints sit around 1024-1200px. Set it below that and you get tablet layout. 1440×900 for desktop, 375×812 for mobile. Saves a lot of head-scratching.
Screenshot tip: if your captures look like the mobile version of a site, check your viewport width. Most responsive breakpoints sit around 1024-1200px. Set it below that and you get tablet layout. 1440×900 for desktop, 375×812 for mobile. Saves a lot of head-scratching.
your cron job ran last night. probably. you didn't check, did you? been using WatchCron for a few weeks now — it pings me when a scheduled task doesn't report in. found two jobs that had been quietly failing for a month. the sca…
your cron job ran last night. probably. you didn't check, did you? been using WatchCron for a few weeks now — it pings me when a scheduled task doesn't report in. found two jobs that had been quietly failing for a month. the sca…
Half of "production monitoring" is just remembering to watch the boring stuff.
Half of "production monitoring" is just remembering to watch the boring stuff.
Page returned 200. Tests passed. Layout was wrecked.
Screenshots don't lie.
Page returned 200. Tests passed. Layout was wrecked.
Screenshots don't lie.
Started this account to talk about web development, APIs, and the small details that make or break a project. No sales pitches — just notes from the trenches.
Started this account to talk about web development, APIs, and the small details that make or break a project. No sales pitches — just notes from the trenches.