We have a bulk import task running in SQL Server 2016 which imports more than 5 million rows. The task itself is configured at cloud using third party services. The strange thing is that the new data being imported is appended to the data file (.mdf) and already allocated empty space is not being used. Tables are being truncated and reloaded. All the tables have clustered indexes defined. We have even used pre-processing task of truncate all related tables -> reorganize all related tables -> DBCC updateusage but to no avail. We have even double the size of the data file but we still see some auto growth events. Although such events decreased by 80 percent. After the import we are left with 70 percent of data file being empty. Am I missing something or any specific setting/change in SQL Server 2016 which is why we are experiencing such behavior? Thanks.
Bulk inserts with small batch sizes can result in a significant increase in unused reserved space due to a full extent allocation for each batch for fast inserts per this Tiger Team post. I see from your comment that the batch size is only 200 rows and this explains the main reason for the large amount of unused space, although I would expect existing unallocated extents (not to be confused with unused space) to be reused before growing the file.
If you don't have control over the optimal batch size (e.g. third-party application), you can turn on trace flag 692 to disable fast inserts and reduce space needs but at the expense of performance.