You’ll potentially destroy your API calls if you make individual association calls in response to high-volume end user activities. The REST API isn’t built for that kind of transactional volume and shouldn’t be used that way. At the very least, you must enforce your own rate limits before opening connections to Marketo.
The safest practice, regardless of projected volume, is to submit a hidden Marketo form from the browser that contains only the Email Address, in addition to posting the custom form to your CMS. Marketo forms have, in practice, no rate limit.
Note if the person doesn’t exist in Marketo yet and your CMS writes to a Marketo-synced CRM, that’ll create an immediate duplicate when the person syncs over from the CRM. You can write webhook-based processes to automatically merge the Marketo-only person with its companion that came over from the CRM. (Unlike other dedupe logic, the rules for this are relatively easy to express because the Marketo-only person has only an Email Address and one easily identifiable action.)
Another option is to store the Marketo Munchkin cookie(s) in a custom string field that’s synced between the CRM and Marketo. Then in Marketo, pick up that value and call the Associate Lead endpoint via a webhook.