Efficiently broadcasting infrequent messages to clients

I’m writing a remote application, controlled by a server. The client would be some sort of daemon that’s pretty much always on. The thing is — these remote commands are unpredictable and sparse. The server could go hours or days without sending a message, or it could send several messages in an hour.

I have no experience with networking, so I’m not sure how all this works and I just need pointers for where to look.

What’s the best, most efficient (cheapest) way to do this? I’d be using AWS for all of this.

The first option I thought of, was to store in a database the IPs of all the clients associated with their user ID. When a AWS Lambda function is called, it makes a new connection to the IP associated with that user id, and sends the message, then closes the connection as the lambda function exits.

The second option was to host an EC2 instance, and actively keep alive connections to all the users. But this would require hosting the EC2 24/7 with potentially a lot of clients, and could get very expensive.

I’m not sure what best practice is here, or even what protocols to look into for that kind of thing. For example, on the first option, how would the server connect to the client? Wouldn’t it have to port forward because of firewalls or something?

Again, I don’t have any experience with network programming so I’ll take all the pointers I can get as to how this is generally accomplished.