foreach my $request (@$hold_requests) { ... foreach my $item (@$available_items) { ... if ($local_hold_match) if ( exists $items_by_itemnumber{ $item->{itemnumber} } and not exists $allocated_items{ $item->{itemnumber} } and not $request->{allocated} ) { This code checks each item for local holds priority and then goes to the next item if request is already allocated, but we should check earlier in the loop and go to the next request if the first one is already filled.