This is a large table.  In such cases, it usually works better to create a new temporary table, truncate the original, and re-insert the data:
create temporary table temp as 
    select max(id), lower(domain), status
    from mytable
    group by lower(domain), status;
truncate table mytable;
insert into mytable(id, domain, status)
    select id, domain, status
    from temp;
This assumes that you can take the big table offline for a while for the re-insertion.  Otherwise, you'll need to delete in batches.
If you want to do it as a delete, I would still start with the same temporary table and add an index on id.  Then do:
delete m
    from mytable m left join
         temp
         on m.id = temp.id
    where temp.id is null;
You can add a limit clause, such as limit 10000 to run this in batches.
NOTE:
The assumption is that you don't care which of the rows to keep.  If you just want the biggest id, then use:
create temporary table temp as 
    select id, lower(domain), status
    from mytable m
    where not exists (select 1
                      from mytable m2
                      where lower(m2.domain) = lower(m.domain) and m2.id > m.id
                     );
To be honest, though, this will have poor performance.  I would check your local settings to see if comparisons are case sensitive or not.  If they are not, just add an index on mytable(domain, id) for the above query.  If they are, then put everything in the same case:
update mytable
    set domain = lower(domain);
And create the index on mytable(domain, id).