Multiple options:
Batch class callout
You can use
Database.GetUpdatedResult r = Database.getUpdated(
'Object API Name',
StartDateTime,
EndDateTime
);
and send the records to the external system via callout in batches of 100, as there is no limit on ApexCallout being made from apex, you can schedule this after the bulk update is done.
Cons
Custom approach. Code maintenance. Security
Heroku Connect
Use Heroku connect
to sync the data to a database hosted in Heroku. This internally uses Platform event or polling mechanism which is configurable.
In you case polling for every 30 minutes should work fine.
No code, Mostly configuration, secure.
Cons
Skillset is required to run heroku and configure it.
Pull data via Bulk API
Have external System pull data from Salesforce as a nightly job. While doing a bulk data load mark the records with a flag which needs to be sent to external system.
Then you can query the data via bulkapi BulkV2QueryJobs
and fetch the data.
Cons: Not sure
CDC or Platform Events
This may work on small set of data, but it has will fail with Large data volumes, as these are have same limit of delivery. And will have to incur additional costs to support for huge data sets, as the default limit is very less.
By default this is Secure and Scalable. But Scalable with a cost.
Cons: Costly, and not reliable as the events might get lost in a server failure scenario.