Under the hood, there’s no difference. They both run on Netlify Functions, and thus, are subject to same limitations. But on the surface, there are these differences:
Choose to use Next.js API routes when:
You wish to keep all your application logic is the same structure. For example, if you already have other API routes, or if you’re more familiar with Next.js API, then using that makes more sense.
You need some Next.js-specific functionality. In this case, it’s an obvious choice.
You wish to avoid vendor lock-in. If you choose to stop using Netlify (we hope you don’t ), you can simply take your Next.js codebase and deploy it elsewhere, instead of having to convert your Netlify Functions into some other format.
Choose Netlify Functions when:
You wish to avoid Next.js overhead. It goes without saying that, if you use Next.js API routes, Next.js will do its own processing, which leads to bigger function bundles and a slight delay in function execution time.
Debugging could be easier. For each function, you’d get a separate log, which can make debugging easier, as opposed to just one API handler function in case of Next.js API routes.
You wish to use Netlify-specific stuff like On-demand Builders, Scheduled Functions, etc.