Your development machine has no memory limit worth mentioning, root access and any extension you want. A lot of your buyers are on shared hosting with none of that. An item that assumes your environment excludes them.
Assume no shell access
If your install requires running a command, a meaningful share of buyers cannot do it. Provide a web-based installer as well, even if the command line route is nicer for those who have it.
Assume a modest memory limit
Loading an entire table into memory to process it works locally and fails at 128MB. Process in batches, stream where you can, and never assume the whole result set fits.
Assume execution timeouts
Long jobs get killed part way. Anything that could take more than a few seconds needs to be resumable: process a chunk, record where you got to, continue. A migration that dies half way and cannot be re-run is a support ticket you cannot fix remotely.
Do not assume cron
Some plans have it, some make it hard, some hide it. Offer a fallback that triggers scheduled work on request, as many CMS platforms do, so the item still functions.
Check rather than crash
- Extensions you use, by name, at install
- Whether the directories you write to are actually writable
- Whether outbound HTTP is permitted, because plenty of hosts block it
That last one matters for licence checks specifically, which is why the offline grace period exists.
Test it properly
A cheap shared hosting account is a few dollars a month and is the most useful test environment you can own. Install your own item on it before every release.