{"slug": "count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked", "title": "Count usage when a job is accepted—not when the button is clicked", "summary": "A developer building Turner AI, a browser-based AI photo editor, argues that usage should be counted when a job is accepted by the server, not when a user clicks a button. The approach ensures that failed or rejected requests do not penalize users, and it maintains a clear server-side boundary for quota accounting. The developer applies this pattern in Turner AI, a free AI photo editor with no signup required.", "body_md": "I'm building a browser-based AI photo editor with a no-signup editing flow.\n\nOne of the first design choices was deciding what should count as usage.\n\nThe tempting implementation is simple:\n\nUser clicks “Edit” -> decrement quota\n\nBut a click is only intent. It is not yet an accepted unit of work.\n\nA request can fail validation, fail before the upload is usable, or be rejected by the service before a job exists. Counting any of those as AI usage turns product or reliability friction into a user penalty.\n\nFor anonymous capacity controls, I use a different unit:\n\nOne successfully accepted job consumes one unit of anonymous quota.\n\nThe server validates and authorizes the request, then creates the job and records the accepted attempt in the same transaction.\n\n```\nBEGIN\n  validate and authorize the request\n  create the job\n  record one accepted quota attempt\nCOMMIT\n```\n\nIf that transaction does not commit, there is no job and nothing is counted.\n\nThis also makes the system easier to reason about. Admission accounting happens once, at a clear server-side boundary. Later lifecycle events are recorded separately:\n\nThose are useful signals for reliability and product quality, but they should not be confused with a browser click.\n\nThe browser can still provide immediate feedback and discourage accidental repeat submissions. It is a UX layer, not the enforcement boundary. The service remains the source of truth for request admission and quota accounting.\n\nThere is an important distinction here: an anonymous capacity quota is not the same thing as a paid credit system. If a product later sells credits, failed-result reversal or refund behavior needs its own explicit settlement policy. Reusing an anti-abuse quota rule for billing would be a mistake.\n\nI'm applying this pattern in Turner AI, a free AI photo editor - no signup, no watermark：[https://turner.art](https://turner.art)\n\nFor anonymous capacity controls, would you count an accepted job, an inference start, or only a successful output?", "url": "https://wpnews.pro/news/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked", "canonical_source": "https://dev.to/nenoke/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked-5e41", "published_at": "2026-07-16 10:26:22+00:00", "updated_at": "2026-07-16 10:34:05.124476+00:00", "lang": "en", "topics": ["ai-products", "developer-tools", "ai-infrastructure"], "entities": ["Turner AI", "Turner.art"], "alternates": {"html": "https://wpnews.pro/news/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked", "markdown": "https://wpnews.pro/news/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked.md", "text": "https://wpnews.pro/news/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked.txt", "jsonld": "https://wpnews.pro/news/count-usage-when-a-job-is-accepted-not-when-the-button-is-clicked.jsonld"}}