oss
oss3mo ago

How to add to code limits for free plan?

I've noticed that my public app in the apify app store has a huge amount of usage from free plan users and the revenue is in the high tens of dollars negative. Can anyone point me in the direction on how to limit the free plan users for example to 100 outputs per run? thanks!
12 Replies
!!!Joefree!!! 👑
Best practices for PPR Actors To ensure profitable operation: Set memory limits in your actor.json file to control platform usage costs Implement the ACTOR_MAX_PAID_DATASET_ITEMS check to prevent excess result generation. You can copy this simple solution. Test your Actor with various result volumes to determine optimal pricing Push at least one "error item" to the dataset for invalid input or if search query didn't generate any result. This will prevent users running your Actor for free.
!!!Joefree!!! 👑
Monetize your Actor | Platform | Apify Documentation
Learn how you can monetize your web scraping and automation projects by publishing Actors to users in Apify Store.
oss
ossOP3mo ago
thanks. looking into this 🙂 i checked it and if i'm not mistaken, ACTOR_MAX_PAID_DATASET_ITEMS can be changed by a free user so this doesnt fit. is there any other way to figure out the plan?
aciku
aciku3mo ago
Ways to limit/manage usage in your Apify actor 1️⃣ Per-run limit based on user plan • Read Apify’s environment variables: • APIFY_USER_PRICING_TIER (e.g., FREE) • APIFY_USER_IS_PAYING • Once the actor reaches X results in a run, stop execution gracefully with a message like: “Limit reached in this run: delivered 100 results.” • Downside: users can still launch multiple runs to bypass the cap. 2️⃣ Monthly quota per user • Define, for example, 100 results/month for free users. • Persist usage in Apify’s Key-Value Store (KVS):
{ "userId": "12345", "month": "2025-09", "resultsUsed": 87 }
{ "userId": "12345", "month": "2025-09", "resultsUsed": 87 }
• On each run: • Read the counter; if resultsUsed + new > 100 → abort with a “quota exhausted” message. • Otherwise, process and update the KVS. • Advantage: quotas reset automatically each month without needing extra infrastructure. 3️⃣ External control (own database + API) • Host your own API + DB on a VPS (OVH/Hetzner/etc.). • The actor queries your API to: • check remaining usage, • debit consumption, • apply advanced logic • Advantage: maximum control and detailed analytics. • Downside: higher DevOps overhead. 4️⃣ Pay-per-event pricing by tier (aligns with Apify credits) • Define price per result based on the user’s tier: • FREE: e.g., $0.05 per result → with 100 results they consume the free $5 Apify credit. • PAID (BRONZE, SILVER, GOLD): e.g., $0.002–$0.01 per result (much cheaper for paying customers).
oss
ossOP3mo ago
thanks for the all the details and options. i'm on it, looking into all of them. you're the best!
MEE6
MEE63mo ago
@oss just advanced to level 1! Thanks for your contributions! 🎉
TimCoulter
TimCoulter3mo ago
Thanks for sharing that list of recommendations - it is very enlightening. However, I am a bit confused about the viability of option 2. If the tracking data is stored in the KVS, it resides in the user's account, not mine, doesn't it? If so, can't the user simply delete the tracking file to bypass the usage limit? And why do we need to store the user ID, if only one user's tracking data will exist in that file?
aciku
aciku3mo ago
You could store it either in your KVS or in the user’s. I would prefer keeping it in the creator’s KVS, since as you mentioned, the user could simply delete it otherwise. If you store it in the creator’s KVS, then the userId becomes important in order to track how many results each user has consumed.
TimCoulter
TimCoulter3mo ago
Thanks for clarifying. I wasn't even aware that an actor can save to the creator's KVS, but you have opened my eyes! That offers many possibilities. Thanks 🙂
MEE6
MEE63mo ago
@TimCoulter just advanced to level 2! Thanks for your contributions! 🎉
xMiso
xMiso3mo ago
I don't think you can store data about users run in your own KVS, or it was impossible few months ago I tried to solve exactly this problem.
aciku
aciku3mo ago
You need to use your own token, because the token in the environment variables belongs to the user. So, set your token in the environment variables under a different name.

Did you find this page helpful?