How to apply outer limit offset and filters in the subquery to avoid grouping over the complete table used in subquery in Postgresql
I am not sure if this is really more efficient, but you could try to join to a derived table that applies the limit.

select emp.employee_id, emp.salary, adr.address_arr 
from (
  SELECT employee_id, salary, address_arr 
  FROM employee 
    LEFT JOIN payroll on payroll.employee_id = employee.employee_id
  WHERE employee.employee_id &lt; 1000000
  LIMIT 100
  OFFSET 0
) as emp
  JOIN (
     SELECT a.employee_id, ARRAY_AGG(a.address) as address_arr 
     FROM addresses a
     GROUP BY employee_id
  ) as adr ON adr.employee_id = emp.employee_id;


The first derived table only selects 100 rows, and the join/group by should then only be done for those 100 employees. 

If the optimizer doesn't push that down, you could try a lateral join instead to "force" a push down:

select emp.employee_id, emp.salary, adr.address_arr 
from (
  SELECT employee_id, salary, address_arr 
  FROM employee 
    LEFT JOIN payroll on payroll.employee_id = employee.employee_id
  WHERE employee.employee_id &lt; 1000000
  LIMIT 100
  OFFSET 0
) as emp
  LATERAL JOIN (
     SELECT a.employee_id, ARRAY_AGG(a.address) as address_arr 
     FROM addresses a
     WHERE a.employee_id = emp.employee_id
     GROUP BY employee_id
  ) as adr ON adr.employee_id = emp.employee_id;


The join condition isn't really needed, but it dosn't hurt either