We simply send emails using gmail API. They are personalized a bit, I run everything from jupyter notebook. Not a big fan of services like mailchimp. We keep personal approach so I prefer to land in primary inbox vs "promotions" as most customers are businesses and we've had exchanges over the email. We're just under 2k which is the daily limit for gmail, will start using SMTP with it since that gets you 10k emails a day.
It's embarrassingly primitive, we export all existing subscribers into csv from our CRM, I load it into pandas dataframe and send using simple for loop + gmail api calls. I run it with "caffeinate" terminal command and use time.sleep() to time the sending for the morning as I tend to wake up pretty late. Other times when I'm travelling I just push updated csv into google cloud vm and let it run there.
A more advanced setup would be sqlite + keeping timestamps, message and thread ids for future work e.g. analytics on responses.