GetRecordsFromDbAsync is an async method, so your top level async method (which is called by the async-supporting ASP.NET web server) just hands over its asyncness to the next level.
All the way down until GetRecordsFromDbAsync or its descendants actually calls the last async method in the call stack. There it presumably becomes native and will it register an I/O interrupt or something else which gets called when the file is read, the web request is handled, etc.