After saving the cert, I used PHP openssl_x509_check_private_key() between the cert and key, however it returns false, i.e. the cert does not match with the key.
With most ACME clients, if you don't specifically tell them to reuse the same private key, they will always generate a new one for each renewal. For example, this is true for Certbot if you don't specifically supply the --reuse-key option.
It's my own code, while I'm a #lowcode guy, the custom code is avoid a 1 hour per domain wait time due to my DNS provider's TTL because I'm using wildcard certs which requires DNS01.
Perhaps my question is, isn't the cert renewed based on my CSR (which is paired with my key)?
How is it that I end up with a cert that does not match the key?
PS I'm looking to see if I submitted a wrong CSR, but clarifying my understanding above will help alot.
If your Let's Encrypt client does submit a (pre-existing) CSR, then yes, the private key should not change. But again, note that this isn't the default behavior of the great majority of Let's Encrypt clients, so unless you specifically selected a particular CSR and asked for a new certificate based on that, it probably wasn't re-used.
It's totally fine from the certificate authority's point of view, but it may not match up well with the workflow expected by most client software, in which case you may end up finding it difficult or cumbersome. Most Let's Encrypt clients don't make it especially convenient to provide your own CSR at all.
Hard to say without knowing a lot more about your environment and more... but likely not "bad".
But it can be said, in general, that changing keys is usually regarded better than not changing keys.
How much better? - this depends entirely on your security posture
Is it worth the effort? - this depends on the difficulty within your design/use and much on your own opinion