Meta Query returns wrong number of posts

$posts is a reserved global variables which stores the value from the $posts property from the main query. By using $posts as a local variable, you are breaking the main query and the $posts global variable. This leads to unexpected output.

You should use unique custom variables as local variables. You can solve your issue by changing

$posts = get_posts( $args );

to something like

$posts_array = get_posts( $args );