The await is waiting, but only inside each callback. forEach calls your async function, gets a promise back, and throws that promise away. It never waits on it, so the loop ends straight away and console.log runs.
Pick based on what you want.
One at a time, in order: use for...of, where await pauses the loop itself:
for (const item of items) {
await saveItem(item);
}
console.log("all done");
All at once: map to promises and wait for all of them:
The second is faster, but if any save rejects, Promise.all rejects straight away. The other saves keep running; you just stop waiting for them. Use Promise.allSettled if you need every result regardless.
Worth saying: "all at once" with 5,000 items means 5,000 requests at the same moment, and most APIs will rate-limit you for that. For big lists, process them in chunks of, say, 20 with Promise.all per chunk.