I just started typing that....
My more modern advice, based on more knowledge, is that tag event scripts (on the tag) should run in single digits milliseconds, no exceptions. That means you cannot use any system.* functions that would wait on a database or wait on any network exchange. And never sleep or busy-wait. You cannot use system.tag.writeBlocking() on anything but memory tags. You cannot interact with the DB except via system.db.runSFPrepUpdate(). You cannot use system.opc.* at all. You cannot call out to any web API.
Tag Change Events defined in a project get their own thread, so can do more "bad" things.