While TCP has a concept of connections that have a beginning and an end, UDP does not have that. UDP is a connectionless protocol: an UDP receiver simply waits for incoming packets in a specified UDP port and outputs the content of any arriving UDP packets.
nc has no clue about how many packets might be incoming, nor whether those packets should all be coming in from the same host, or from several hosts: it simply receives anything that arrives to the specified UDP port and outputs the contents of the UDP packets to standard output without parsing it in any way until the
nc process is interrupted.
There is not even any built-in guarantee that any packets sent by the client/sender are received in the same order at the receiver end: packets might be lost or reordered on the way. UDP makes no attempt to fix that: it's the job of the thing that is using UDP to deal with all those issues (or ignore them) as appropriate for its purposes.
You might decide on a specific string, make it mean "end of data" and arrange for another script at the listening end to parse the incoming data and kill the listening
nc process when that string is received. In that way, you'll start building your own (perhaps very simple) protocol on top of UDP. And that is exactly what UDP was designed for.
In a nutshell, the answer to "Is it possible to have
nc -ul terminate automatically?" is "No, unless you make something that does it."